使用matplotlib的savefig函数保存由Python pandas生成的图表(AxesSubPlot)。

139

我正在使用pandas从数据框生成图表,我想将其保存到文件中:

dtf = pd.DataFrame.from_records(d,columns=h)
fig = plt.figure()
ax = dtf2.plot()
ax = fig.add_subplot(ax)
fig.savefig('~/Documents/output.png')

似乎最后一行使用了matplotlib的savefig,应该可以解决问题。但是这段代码产生了以下错误:
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

另外,试图直接在绘图上调用savefig也会出错。
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'

我觉得我需要以某种方式将plot()返回的子情节添加到图形中,以便使用savefig。我也想知道这是否与AxesSubPlot类背后的magic有关。
编辑:
以下方法可以运行(没有错误),但是给我留下了一个空白页面图像...
fig = plt.figure()
dtf2.plot()
fig.savefig('output.png')

编辑2: 下面的代码也可以正常工作。
dtf2.plot().get_figure().savefig('output.png')
6个回答

167

在版本0.14中gcf方法已被弃用,以下代码对我有效:

plot = dtf.plot()
fig = plot.get_figure()
fig.savefig("output.png")

43
你可以使用ax.figure.savefig(),这是在问题的评论中建议的做法:
import pandas as pd

df = pd.DataFrame([0, 1])
ax = df.plot.line()
ax.figure.savefig('demo-file.pdf')

按照其他答案建议,这与ax.get_figure().savefig()相比没有实际的好处,因此您可以选择您认为最美观的选项。事实上,get_figure()只是返回self.figure

# Source from snippet linked above
def get_figure(self):
    """Return the `.Figure` instance the artist belongs to."""
    return self.figure

20

所以我并不完全确定为什么这样会起作用,但它保存了我的图像:

dtf = pd.DataFrame.from_records(d,columns=h)
dtf2.plot()
fig = plt.gcf()
fig.savefig('output.png')

我猜测,原始帖子中最后一段代码未正常保存是因为该图形从未由pandas生成轴。通过上述代码,图形对象通过gcf()调用(获取当前图形),从某个神奇的全局状态返回,并自动将在上一行中绘制的轴烘焙进去。


15

在使用plot()函数之后,使用plt.savefig()函数似乎很容易:

import matplotlib.pyplot as plt
dtf = pd.DataFrame.from_records(d,columns=h)
dtf.plot()
plt.savefig('~/Documents/output.png')

12
  • 其他答案解决了单个绘图的保存问题,而不是子图。
  • 在存在子图的情况下,绘图API返回一个numpy.ndarray,其中包含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

使用pandas.DataFrame.plot()绘图

  • 以下示例使用kind='hist',但指定其他内容时解决方案相同。
  • 使用[0]获取数组中的一个axes,并使用.get_figure()提取图形。
fig = df.plot(kind='hist', subplots=True, figsize=(6, 6))[0].get_figure()
plt.tight_layout()
fig.savefig('test.png')

这里输入图片描述

使用 pandas.DataFrame.hist() 绘图

1:

  • 在此示例中,我们将 df.hist 分配给用 plt.subplots 创建的 Axes,并保存该 fig
  • 用于 nrowsncols 的值分别为 41,但其他配置也可以使用,例如 22
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:

  • 使用.ravel()函数来展平Axes数组
fig = df.hist().ravel()[0].get_figure()
plt.tight_layout()
fig.savefig('test.png')

在这里输入图片描述


2
.get_figure() 是我正在寻找的。谢谢。 - Matthew Son
使用 .ravel() 方法是与 Kedro 最适合配合使用的方法。 - undefined

4
这可能是一种更简单的方法:
(DesiredFigure).get_figure().savefig('figure_name.png')
即:
dfcorr.hist(bins=50).get_figure().savefig('correlation_histogram.png')

请问您能否提供一个例子并加以更详细的解释? - Noordeen
1
如果您在同一函数内创建多个图形,则此方法无效(但在Jupyter笔记本单元格中有效)。 - Jonathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接