![](/img/trans.png)
[英]Saving plots (AxesSubPlot) generated from python pandas with matplotlib's savefig
[英]matplotlib savefig() plots different from show()
当我使用show()
在X
绘制图形时,图形看起来非常好。 但是当我开始使用savefig()
生成大量图形时, savefig()
生成的图形的字体,线条,多边形看起来都比show()
生成的图形小。 我的环境是Ubuntu, show()
的后端是Qt4Agg
。 如何使show()
图和savefig()
图看起来一致?
savefig
指定已保存图形的DPI(如果未在.matplotlibrc中指定,则默认值为100,请查看savefig的dpi
savefig
)。 它并没有从原始数字的DPI中得到它。
DPI会影响文本的相对大小和线条上笔画的宽度等。如果您希望看起来相同, fig.dpi
fig.savefig
传递给fig.savefig
。
例如
import matplotlib.pyplot as plt
fig = plt.figure()
plt.plot(range(10))
fig.savefig('temp.png', dpi=fig.dpi)
您将matplotlib图表渲染到不同的设备(例如,通过石英在屏幕上使用不同的函数( plot vs savefig )通过pdf 渲染到参数几乎相同,但这些参数的默认值不相同两个功能。
换句话说,在savefig默认参数是从默认的显示参数不同 。
如果你在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中的第277a 行开始(此部分前面是行:### FIGURE):
figure.figsize : 8, 6
figure.dpi : 80
figure.facecolor : 0.75
figure.edgecolor : white
正如你可以通过比较参数这两个块的值看,对于相同的人物的属性的默认设置是用于savefig与显示器 (显示) 不同 。
老问题,但显然谷歌喜欢它,所以我想我在对这个问题进行一些研究之后给出了答案。
如果您从头开始创建一个图形,则可以在创建时为其指定尺寸选项:
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源代码中修复了这个问题,但这不是一个很好的修复方法。 但是,如果你像我一样非常关注图表的外观,那就值得了。
问题似乎在渲染后端; 它们每个都获得正确的线宽,字体大小等值,但是当渲染为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()中的图像。
莱昂,你有没改变过这个环境?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.