Saving plots (AxesSubPlot) generated from python pandas with matplotlib's savefig
I'm using pandas to generate a plot from a dataframe, which I would like to save to a file:
dtf = pd.DataFrame.from_records(d,columns=h)
fig = plt.figure()
ax = dtf2.plot()
ax = fig.add_subplot(ax)
fig.savefig('~/Documents/output.png')
It seems like the last line, using matplotlib's savefig, should do the trick. But that code produces the following error:
Traceback (most recent call last):
File "./testgraph.py", line 76, in <module>
ax = fig.add_subplot(ax)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/figure.py", line 890, in add_subplot
assert(a.get_figure() is self)
AssertionError
Alternatively, trying to call savefig directly on the plot also errors out:
dtf2.plot().savefig('~/Documents/output.png')
File "./testgraph.py", line 79, in <module>
dtf2.plot().savefig('~/Documents/output.png')
AttributeError: 'AxesSubplot' object has no attribute 'savefig'
I think I need to somehow add the subplot returned by plot() to a figure in order to use savefig. I also wonder if perhaps this has to do with the magic behind the AxesSubPlot class.
EDIT:
the following works (raising no error), but leaves me with a blank page image....
fig = plt.figure()
dtf2.plot()
fig.savefig('output.png')
EDIT 2: The below code works fine as well
dtf2.plot().get_figure().savefig('output.png')
The gcf method is depricated in V 0.14, The below code works for me:
plot = dtf.plot()
fig = plot.get_figure()
fig.savefig("output.png")
You can use ax.figure.savefig()
, as suggested in a comment on the question:
import pandas as pd
df = pd.DataFrame([0, 1])
ax = df.plot.line()
ax.figure.savefig('demo-file.pdf')
This has no practical benefit over ax.get_figure().savefig()
as suggested in other answers, so you can pick the option you find the most aesthetically pleasing. In fact, get_figure()
simply returns self.figure
:
# Source from snippet linked above
def get_figure(self):
"""Return the `.Figure` instance the artist belongs to."""
return self.figure
So I'm not entirely sure why this works, but it saves an image with my plot:
dtf = pd.DataFrame.from_records(d,columns=h)
dtf2.plot()
fig = plt.gcf()
fig.savefig('output.png')
I'm guessing that the last snippet from my original post saved blank because the figure was never getting the axes generated by pandas. With the above code, the figure object is returned from some magic global state by the gcf() call (get current figure), which automagically bakes in axes plotted in the line above.
It seems easy for me that use plt.savefig()
function after plot()
function:
import matplotlib.pyplot as plt
dtf = pd.DataFrame.from_records(d,columns=h)
dtf.plot()
plt.savefig('~/Documents/output.png')
- The other answers deal with saving the plot for a single plot, not subplots.
- In the case where there are subplots, the plot API returns an
numpy.ndarray
ofmatplotlib.axes.Axes
import pandas as pd
import seaborn as sns # for sample data
import matplotlib.pyplot as plt
# load data
df = sns.load_dataset('iris')
# display(df.head())
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
Plot with pandas.DataFrame.plot()
- The following example uses
kind='hist'
, but is the same solution when specifying something other than'hist'
- Use
[0]
to get one of theaxes
from the array, and extract the figure with.get_figure()
.
fig = df.plot(kind='hist', subplots=True, figsize=(6, 6))[0].get_figure()
plt.tight_layout()
fig.savefig('test.png')
Plot with pandas.DataFrame.hist()
1:
- In this example we assign
df.hist
toAxes
created withplt.subplots
, and save thatfig
. -
4
and1
are used fornrows
andncols
, respectively, but other configurations can be used, such as2
and2
.
fig, ax = plt.subplots(nrows=4, ncols=1, figsize=(6, 6))
df.hist(ax=ax)
plt.tight_layout()
fig.savefig('test.png')
2:
- Use
.ravel()
to flatten the array ofAxes
fig = df.hist().ravel()[0].get_figure()
plt.tight_layout()
fig.savefig('test.png')