当我使用show()
在X
中绘制图形时,图形看起来非常好。然而,当我开始使用savefig()
生成大量的图形时,savefig()
生成的图形的字体、线条和多边形都比show()
生成的图形要小。我的环境是Ubuntu,show()
的后端是Qt4Agg
。如何使show()
绘图和savefig()
绘图看起来一致?
当我使用show()
在X
中绘制图形时,图形看起来非常好。然而,当我开始使用savefig()
生成大量的图形时,savefig()
生成的图形的字体、线条和多边形都比show()
生成的图形要小。我的环境是Ubuntu,show()
的后端是Qt4Agg
。如何使show()
绘图和savefig()
绘图看起来一致?
savefig
指定了保存图形的 DPI(如果在您的 .matplotlibrc 中没有指定,默认为 100,请查看 savefig
的 dpi
kwarg)。它不会继承原始图形的 DPI。fig.dpi
传递给 fig.savefig
。import matplotlib.pyplot as plt
fig = plt.figure()
plt.plot(range(10))
fig.savefig('temp.png', dpi=fig.dpi)
虽然这是一个老问题,但显然谷歌很喜欢它,所以我在研究了这个问题之后想在这里回答一下。
如果您从零开始创建一个图形,您可以在创建时为其指定一个大小选项:
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(width,height) 调整您的图表的绝对尺寸,有助于确保两个图表看起来相同。
如其他回答中所述,dpi 选项会影响文本的相对大小和线条宽度等。使用 dpi=fig.dpi 选项可以确保在 show() 和 savefig() 中这些元素的相对大小相同。
或者,也可以在创建后更改图形大小:
fig.set_size_inches(3, 6, forward=True)
forward 能够随时更改大小。
如果您在创建的图像中遇到边框过大的问题,可以使用以下方法进行调整:
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()图像的问题。
你会通过不同的方式来渲染你的 matplotlib 图形(例如通过 Quartz 在屏幕上显示或者通过使用不同的函数(plot 与 savefig)将其保存为 PDF 文件),这些函数的参数几乎相同,但这些函数的默认参数并不相同。
换句话说,savefig 的默认参数与默认的display参数不同。
如果你想要使它们保持一致,可以在 matplotlib 配置文件 中很容易地完成。模板文件包含在源码包中,并命名为 matplotlibrc.template。如果在安装 matplotlib 时没有创建该文件,可以从 matplotlib 源代码或matplotlib 网站获取此模板。
自定义此文件后,将其重命名为 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() 处开始,位于 matplotlibrc.template 的大约第 277 行(此部分前面有一行注释:### FIGURE):
figure.figsize : 8, 6
figure.dpi : 80
figure.facecolor : 0.75
figure.edgecolor : white
通过比较这两个参数块的值,您可以看到同一图形属性的默认设置在保存图片与显示图片时是不同的。
我在我的matplotlib源代码中修复了这个问题,但解决方法不是很完美。然而,如果你像我一样非常注重图表的外观,那么它是值得的。
问题似乎出现在渲染后端中;它们都获得了正确的linewidth,字体大小等数值,但在渲染为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)