当我使用show()
绘制X
中的图表时,图表看起来非常好。但是,当我开始使用savefig()
生成大量图表时,savefig()
生成了图表
'字体,线条,多边形看起来都比show()
生成的图形小。我的环境是Ubuntu,show()
的后端是Qt4Agg
。如何使show()
图和savefig()
图看起来一致?
答案 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()中的图像。
莱昂,你有没改变过那个环境?