143

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')
0

6 Answers 6

171

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")
Sign up to request clarification or add additional context in comments.

Comments

45

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

Comments

20

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.

Comments

16

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')

Comments

16
  • 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 of matplotlib.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 the axes 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')

enter image description here

Plot with pandas.DataFrame.hist()

1:

  • In this example we assign df.hist to Axes created with plt.subplots, and save that fig.
  • 4 and 1 are used for nrows and ncols, respectively, but other configurations can be used, such as 2 and 2.
fig, ax = plt.subplots(nrows=4, ncols=1, figsize=(6, 6))
df.hist(ax=ax)
plt.tight_layout()
fig.savefig('test.png')

enter image description here

2:

  • Use .ravel() to flatten the array of Axes
fig = df.hist().ravel()[0].get_figure()
plt.tight_layout()
fig.savefig('test.png')

enter image description here

1 Comment

The method with .ravel() was the most suitable to be used with Kedro
4

this may be a simpler approach:

(DesiredFigure).get_figure().savefig('figure_name.png')

i.e.

dfcorr.hist(bins=50).get_figure().savefig('correlation_histogram.png')

2 Comments

can you please add some more explanation with an example?
this doesn't work if you are creating multiple figures within the same function (but does work in jupyter notebook cells).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.