How to save a Seaborn plot into a file - python

I tried the following code (test_seaborn.py):
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
matplotlib.style.use('ggplot')
import seaborn as sns
sns.set()
df = sns.load_dataset('iris')
sns_plot = sns.pairplot(df, hue='species', size=2.5)
fig = sns_plot.get_figure()
fig.savefig("output.png")
#sns.plt.show()
But I get this error:
Traceback (most recent call last):
File "test_searborn.py", line 11, in <module>
fig = sns_plot.get_figure()
AttributeError: 'PairGrid' object has no attribute 'get_figure'
I expect the final output.png will exist and look like this:
How can I resolve the problem?

The following calls allow you to access the figure (Seaborn 0.8.1 compatible):
swarm_plot = sns.swarmplot(...)
fig = swarm_plot.get_figure()
fig.savefig("out.png")
as seen previously in this answer.
The suggested solutions are incompatible with Seaborn 0.8.1. They give the following errors because the Seaborn interface has changed:
AttributeError: 'AxesSubplot' object has no attribute 'fig'
When trying to access the figure
AttributeError: 'AxesSubplot' object has no attribute 'savefig'
when trying to use the savefig directly as a function
UPDATE:
I have recently used PairGrid object from seaborn to generate a plot similar to the one in this example.
In this case, since GridPlot is not a plot object like, for example, sns.swarmplot, it has no get_figure() function.
It is possible to directly access the matplotlib figure by:
fig = myGridPlotObject.fig

Some of the above solutions did not work for me. The .fig attribute was not found when I tried that and I was unable to use .savefig() directly. However, what did work was:
sns_plot.figure.savefig("output.png")
I am a newer Python user, so I do not know if this is due to an update. I wanted to mention it in case anybody else runs into the same issues as I did.

Fewer lines for 2019 searchers:
import matplotlib.pyplot as plt
import seaborn as sns
df = sns.load_dataset('iris')
sns_plot = sns.pairplot(df, hue='species', height=2.5)
plt.savefig('output.png')
UPDATE NOTE: size was changed to height.

You should just be able to use the savefig method of sns_plot directly.
sns_plot.savefig("output.png")
For clarity with your code if you did want to access the matplotlib figure that sns_plot resides in then you can get it directly with
fig = sns_plot.fig
In this case there is no get_figure method as your code assumes.

I use distplot and get_figure to save picture successfully.
sns_hist = sns.distplot(df_train['SalePrice'])
fig = sns_hist.get_figure()
fig.savefig('hist.png')

I couldnt get the other answers to work and finally got this to work for me for matplotlib==3.2.1 . Its especially true if you are doing this within a for loop or some iterative approach.
sns.scatterplot(
data=df_hourly, x="date_week", y="value",hue='variable'
)
plt.savefig('./f1.png')
plt.show()
Note that the savefig must be before the show call. Otherwise an empty image is saved.

This works for me
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
sns.factorplot(x='holiday',data=data,kind='count',size=5,aspect=1)
plt.savefig('holiday-vs-count.png')

Its also possible to just create a matplotlib figure object and then use plt.savefig(...):
from matplotlib import pyplot as plt
import seaborn as sns
import pandas as pd
df = sns.load_dataset('iris')
plt.figure() # Push new figure on stack
sns_plot = sns.pairplot(df, hue='species', size=2.5)
plt.savefig('output.png') # Save that figure

You would get an error for using sns.figure.savefig("output.png") in seaborn 0.8.1.
Instead use:
import seaborn as sns
df = sns.load_dataset('iris')
sns_plot = sns.pairplot(df, hue='species', size=2.5)
sns_plot.savefig("output.png")

Just FYI, the below command worked in seaborn 0.8.1 so I guess the initial answer is still valid.
sns_plot = sns.pairplot(data, hue='species', size=3)
sns_plot.savefig("output.png")

Related

How can I make a scatter plot using proplot? (Python)

I just downloaded the ProPlot package and am wondering how I can make a scatter plot. I looked into this example, but as I tried
import proplot as plt
plt.figure(...)
plt.scatter(...)
it returns me AttributeError: module 'proplot' has no attribute 'scatter' . My plot worked when I did
import proplot as plt
import matplotlib.pyplot as plt
plt.figure(...)
plt.scatter(...)
And I did see the effect of proplot in this way. However, I don't think it's right to import two packages with the same notation plt. Is there a better way I can generate the scatter plot using proplot? Thanks!
Proplot does not offer a direct replacement for the scatter plot at the top level of the proplot module. The only way to construct it is to call the method of an axis object:
import proplot as pplt
fig, ax = pplt.subplots()
ax.scatter()
Or alternatively:
fig = pplt.figure()
ax = fig.subplot()
ax.scatter(...)
Note that if you import matplotlib after proplot under the same name plt alias, you won't be able to use the proplot interface under plt since it'll be replaced by matplotlib. It is not "wrong" to do so, since it is legal python, but surely not what you intended to accomplish.

Seaborn Plot is not displaying

I have been trying to plot a simple bar chart using Seaborn. Oddly enough the previous plots worked, but these ones do not appear. No error is being thrown and as far as I can tell the code is okay. Perhaps a more experienced eye will be able to find an error.
import pandas as pd
import numpy as np
import pyodbc
import matplotlib.pyplot as plt
import seaborn as sns
region_pct_25 = region_totals.iloc[0:6, :]
region_pct_25['Opp_Lives_pct'] = ((region_pct_25.Lives / region_pct_25.Lives.sum())*100).round(2)
region_pct_25.reset_index(level=['RegionName'], inplace=True)
region_25_plt = sns.barplot(x="RegionName", y="Opp_Lives_pct", data=region_pct_25, color = 'g').set_title("Client Usage by Region: ADD ")
plt.show()
No plot is showing. Please help wherever you can!
adding %matplotlib inline to the preamble resolved the issue!

How to adjust size of Seaborn distribution graph

I would like to adjust the size of this distribution plot in Seaborn. I tried a few ways from online tutorials and the docs but nothing seemed to actually work. I find this really confusing as it appears different plots such as plt, sns have different functions which don't seem to work interchangeably...
My code:
import seaborn as sns
g = sns.distplot(df['data'])
g.fig.set_figwidth(20)
g.fig.set_figheight(10)
g is an matplotlib.axes._subplots.AxesSubplot (try type(g) to see that). If you do a dir(g) you would see that it has no fig method/attribute. But it has a figure attribute. So change your code to reflect that and you would have what you need.
import seaborn as sns
g = sns.distplot(df['data'])
g.figure.set_figwidth(20)
g.figure.set_figheight(10)
Thanks #Sinan Kurmus's answer, just an alternative solution:
plt.figure(figsize=(30,10)) # Use this line
# plt.gcf().subplots_adjust(left = 0.3)
g = sns.distplot(df['data'])

Issues with matplotlib attribute errors

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
df = pd.read_csv('Iris.csv')
plot = plt.scatter(df['SepalLengthCm'], df['PetalLengthCm'])
plot.savefig('ScatterIris.png')
I'm trying to do some really basic matplotlib stuff and it keeps raising errors.
C:\Users\Robert\Anaconda3\python.exe
C:/Users/Robert/PycharmProjects/linear_regression/ML.py
Traceback (most recent call last):
File "C:/Users/Robert/PycharmProjects/linear_regression/ML.py", line 9, in <module>
plot.savefig('ScatterIris.png')
AttributeError: 'PathCollection' object has no attribute 'savefig'
First I couldn't use the .show() attribute and then I couldn't use the .savefig() attribute. Is there something wrong with my matplotlib installation?
For reference I tried changing the backend of my matplotib in matplotlibrc to a couple different ones and the same error everytime.
Edit # nbryans
plt.scatter(df['SepalLengthCm'], df['PetalLengthCm']).savefig('ScatterIris.png')
Same error comes up
Edit 2:
Yeah you guys were right I can save figures and use the show() attribute/method.
Thanks!
You need to call pyplot's savefig method.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
df = pd.read_csv('Iris.csv')
plt.scatter(df['SepalLengthCm'], df['PetalLengthCm'])
plt.savefig('ScatterIris.png')
The same is true if you were using the pandas plotting function,
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
df = pd.read_csv('Iris.csv')
df.plot(kind="scatter", x='SepalLengthCm', y= 'PetalLengthCm')
plt.savefig('ScatterIris.png')
You don't need to assign a plot variable and you should just do plt.show(). Try:
plt.scatter(df['SepalLengthCm'], df['PetalLengthCm'])
plt.savefig('ScatterIris.png') # or plt.show()
This is because savefig() is a function of pyplot (i.e.plt) and not of the recently createdplot`. It saves whatever the current plot you created is. Thus, it should be:
plt.savefig()
Similarly, just to see your plot, it would be
plt.show()

How modules know each other

I can plot data from a CSV file with the following code:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('test0.csv',delimiter='; ', engine='python')
df.plot(x='Column1', y='Column3')
plt.show()
But I don't understand one thing. How plt.show() knows about df? I'll make more sense to me seeing, somewhere, an expression like:
plt = something(df)
I have to mention I'm just learning Python.
Matplotlib has two "interfaces": a Matlab-style interface and an object-oriented interface.
Plotting with the Matlab-style interface looks like this:
import matplotlib.pyplot as plt
plt.plot(x, y)
plt.show()
The call to plt.plot implicitly creates a figure and an axes on which to draw.
The call to plt.show displays all figures.
Pandas is supporting the Matlab-style interface by implicitly creating a figure and axes for you when df.plot(x='Column1', y='Column3') is called.
Pandas can also use the more flexible object-oriented interface, in which case
your code would look like this:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('test0.csv',delimiter='; ', engine='python')
fig, ax = plt.subplots()
df.plot(ax=ax, x='Column1', y='Column3')
plt.show()
Here the axes, ax, is explicitly created and passed to df.plot, which then
calls ax.plot under the hood.
One case where the object-oriented interface is useful is when you wish to use
df.plot more than once while still drawing on the same axes:
fig, ax = plt.subplots()
df.plot(ax=ax, x='Column1', y='Column3')
df2.plot(ax=ax, x='Column2', y='Column4')
plt.show()
From the pandas docs on plotting:
The plot method on Series and DataFrame is just a simple wrapper
around :meth:plt.plot() <matplotlib.axes.Axes.plot>
So as is, the df.plot method is an highlevel call to plt.plot (using a wrapper), and thereafter, calling plt.show will simply:
display all figures and block until the figures have been closed
as it would with for all figures plotted with plt.plot.
Therefore, you don't see plt = something(df) as you would expect, because matpotlib.pyplot.plot is being called behind the scene by df.plot.
According to http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.show , the plt.show() itself doesn't know about the data, you need to pass the data as parameters.
What you are seeing should be the plot of pandas library, according to the usage http://pandas.pydata.org/pandas-docs/stable/visualization.html#basic-plotting-plot.
Hope this solves your question.

Categories

Resources