matplotlib savefig()绘图与show()不同

时间:2011-10-26 17:17:58

标签: python graph plot matplotlib

当我使用show()绘制X中的图表时,图表看起来非常好。但是,当我开始使用savefig()生成大量图表时,savefig()生成了图表 '字体,线条,多边形看起来都比show()生成的图形小。我的环境是Ubuntu,show()的后端是Qt4Agg。如何使show()图和savefig()图看起来一致?

4 个答案:

答案 0 :(得分:51)

savefig指定已保存图形的DPI(默认值为100,如果未在.matplotlibrc中指定,请查看dpi kwarg to savefig)。它并没有从原始数字的DPI中得到它。

DPI会影响文本的相对大小和线条上笔画的宽度等。如果您希望看起来相同,请将fig.dpi传递给fig.savefig

E.g。

import matplotlib.pyplot as plt

fig = plt.figure()
plt.plot(range(10))
fig.savefig('temp.png', dpi=fig.dpi)

答案 1 :(得分:26)

您将 matplotlib 图表渲染到不同的设备(例如,通过Quartz屏幕上显示,使用不同的功能通过pdf显示到目标文件( plot savefig )其参数几乎相同,但这些参数的默认值对于这两个函数都不相同。

换句话说, savefig 默认参数默认 显示 参数。

如果在 matplotlib配置文件中进行对齐,则对齐它们很简单。模板文件包含在源包中,名为 matplotlibrc.template 。如果您在安装matplotlib时未创建一个,则可以从 matplotlib 源或matplotlib website获取此模板。

按照您希望的方式自定义此文件后,将其重命名为 matplotlibrc (无扩展名)并将其保存到目录 .matplotlib (注意前面的'。')应该在您的主目录中。

保存数字的配置参数从提供的 matplotlibrc.template 中的第314行开始(本节前面的第一行是:# ## SAVING FIGURES)。

特别是,您需要查看以下内容:

savefig.dpi       : 100         # figure dots per inch
savefig.facecolor : white       # figure facecolor when saving
savefig.edgecolor : white       # figure edgecolor when saving
savefig.extension : auto        # what extension to use for savefig('foo'), or 'auto'

这些行下面是字体类型和各种图像格式特定参数的设置。

显示的相同参数,即 PLT.show() ,从约第277行开始 matplotlibrc.template 中的a(此部分前面有一行:### FIGURE):

figure.figsize   : 8, 6          
figure.dpi       : 80            
figure.facecolor : 0.75       
figure.edgecolor : white     

通过比较这两个参数块的值可以看出,相同图形属性的默认设置是 savefig display <的不同 / em>(显示)。

答案 2 :(得分:7)

老问题,但显然谷歌喜欢它,所以我想在对这个问题进行一些研究后,我在这里给出了答案。

如果您从头创建一个图形,则可以在创建时为其指定尺寸选项:

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(3, 6))

plt.plot(range(10)) #plot example
plt.show() #for control

fig.savefig('temp.png', dpi=fig.dpi)

figsize(宽度,高度)调整绘图的绝对尺寸,有助于确保两个图看起来都一样。

如另一个答案中所述, dpi 选项会影响文本的相对大小和线条上的笔画宽度等。使用选项 dpi = fig.dpi 确保 show() savefig()的相对大小相同。

或者,可以在创建后使用以下内容更改图形大小:

fig.set_size_inches(3, 6, forward=True)

转发允许动态更改大小。

如果在创建的图像中有太大的边框时遇到问题,可以使用以下方法调整这些边框:

plt.tight_layout()
#or:
plt.tight_layout(pad=2)

或:

fig.savefig('temp.png', dpi=fig.dpi, bbox_inches='tight')
#or:
fig.savefig('temp.png', dpi=fig.dpi, bbox_inches='tight', pad_inches=0.5)

第一个选项只是最小化布局和边框,第二个选项允许手动调整边框。这些提示至少帮助我解决了我的不同 savefig() show()图像的问题。

答案 3 :(得分:4)

我已经在matplotlib源码中解决了这个问题,但这不是一个很好的修复方法。但是,如果您和我一样,非常关注图表的外观,那么它是值得的。

问题似乎在渲染后端;它们每个都获得正确的线宽,字体大小等值,但是当呈现为PDF或PNG时,与使用show()渲染时相比,它会略大。

我在文件matplotlib / backends / backend_agg.py中添加了几行代码来生成PNG。您可以为您使用的每个后端进行类似的更改,或者找到一种方法在单个位置进行更聪明的更改;)

添加到我的matplotlib / backends / backend_agg.py文件中:

    # The top of the file, added lines 42 - 44
42  # @warning: CHANGED FROM SOURCE to draw thinner lines
43  PATH_SCALAR = .8
44  FONT_SCALAR = .95

    # In the draw_markers method, added lines 90 - 91
89  def draw_markers(self, *kl, **kw):
90      # @warning: CHANGED FROM SOURCE to draw thinner lines
91      kl[0].set_linewidth(kl[0].get_linewidth()*PATH_SCALAR)
92      return self._renderer.draw_markers(*kl, **kw)

    # At the bottom of the draw_path method, added lines 131 - 132:
130 else:
131     # @warning: CHANGED FROM SOURCE to draw thinner lines
132     gc.set_linewidth(gc.get_linewidth()*PATH_SCALAR)
133     self._renderer.draw_path(gc, path, transform, rgbFace)

    # At the bottom of the _get_agg_font method, added line 242 and the *FONT_SCALAR
241     font.clear()
242     # @warning: CHANGED FROM SOURCE to draw thinner lines
243     size = prop.get_size_in_points()*FONT_SCALAR
244     font.set_size(size, self.dpi)

因此,这符合我现在的需求,但是,根据您正在做的事情,您可能希望在其他方法中实施类似的更改。或者在没有这么多换行的情况下找到更好的方法来做同样的事情!

更新:在Github上向matplotlib项目发布问题后,我能够找到问题的根源:我更改了matplotlibrc文件中的figure.dpi设置。如果该值与默认值不同,我的savefig()图像会出现不同,即使我将savefig dpi设置为与图dpi相同。因此,我没有像上面那样更改源代码,而是将figure.dpi设置保留为默认值80,并且能够使用savefig()生成图像,该图像看起来像是show()中的图像。

莱昂,你有没改变过那个环境?