matplotlib出图细节以及提高出图质量(高dpi) 您所在的位置:网站首页 画画dpi是什么意思 matplotlib出图细节以及提高出图质量(高dpi)

matplotlib出图细节以及提高出图质量(高dpi)

2024-07-04 00:30| 来源: 网络整理| 查看: 265

文章目录 省流总结基础知识探究过程matplotlib默认出图(作为参照)改变图片的默认尺寸改变matplotlib的show的dpi 不同backend的影响改变matplotlib的showfig的dpi不同版本matplotlib的showfig低版本matplotlib使用Agg作为backend提高出图质量其他的情况

省流总结 在生成figure时,如fig = plt.figure(figsize=(15,10))不能改变其dpi设定。根据绘图内容,需要确定保存图形最小尺寸,尺寸过小必然影响出图的质量。可以改变show()方法弹出的图像展示窗口尺寸,选出自己满意的尺寸。如发现窗口1000*800像素,显示的图形比较合理,那么就可以确定绘图的尺寸为(1000/100,800/1000),即(10,6).savefig()时,传入要保存的图片的dpi即可,如dpi=600。保存图形时会自动扩大图形像素大小。选择不同的matplotlib的backend。TkAgg比QtAgg好,无交互窗口的Agg出图比TkAgg和QtAgg更好。注意matplotlib版本,有些版本,如3.3.4的matplotlib的savefig和show会相互影响,出现不可预测的问题。升高或者降低版本能解决问题。

原创不易,如果本文对您有帮助的话,还请点赞收藏~

基础知识 屏幕的尺寸:一般以屏幕的对角线尺寸计量,如15.6寸。屏幕分辨率:是值屏幕水平和竖直方向上拥有的物理像素点数。如:分辨率是 1920x1080。ppi: 屏幕每英寸的像素密度是ppi。比如我的电脑屏幕尺寸 15.6,分辨率是 1920x1080,用长(1920)跟高的像素数(1080)计算出对角方向的像素数(直角三角形)(2202),然后再用对角的像素数除以屏幕尺寸(15.6),就得到ppi,即141. 如果我们指定显示图像的显示像素,那么由ppi,就可以得到图像在电脑上显示的物理尺寸。然而我们对电脑屏幕截图时,生成的图像大小的dpi一般是100或者96,更有甚者是72. matplotlib的show()的dpi,我更倾向于理解为它是一种dpi,指定100即可,太高在屏幕上还要进行扩大,并不能提高显示质量。dpi: dpi是打印机的像素密度。而showfig()里的dpi就是这个概念。在科研绘图中,我们一般被要求图片的dpi至少要为300. 本文就是要分析如何生成高质量的高dpi图片。主要是对比不同例子之间的显示差距,方便读者体会。 探究过程 matplotlib默认出图(作为参照)

这里使用的matplotlib的版本是3.4.0,完全使用matplotlib的默认参数。

from mpl_toolkits.axes_grid1 import host_subplot from mpl_toolkits import axisartist import matplotlib import matplotlib.pyplot as plt host = host_subplot(111, axes_class=axisartist.Axes) fig=plt.gcf() print(fig) plt.subplots_adjust(right=0.75) par1 = host.twinx() par2 = host.twinx() par2.axis["right"] = par2.new_fixed_axis(loc="right", offset=(60, 0)) par1.axis["right"].toggle(all=True) par2.axis["right"].toggle(all=True) p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density") p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature") p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity") host.set_xlim(0, 2) host.set_ylim(0, 2) par1.set_ylim(0, 4) par2.set_ylim(1, 65) host.set_xlabel("Distance") host.set_ylabel("Density") par1.set_ylabel("Temperature") par2.set_ylabel("Velocity") host.legend() host.axis["left"].label.set_color(p1.get_color()) par1.axis["right"].label.set_color(p2.get_color()) par2.axis["right"].label.set_color(p3.get_color()) fig=plt.gcf() print(fig) plt.savefig("demo.jpg",dpi=100) fig=plt.gcf() print(fig) plt.show() fig=plt.gcf() print(fig)

控制台打印结果:

Backend Qt5Agg is interactive backend. Turning interactive mode on. Figure(640x480) Figure(640x480) Figure(640x480) Figure(640x480)

在这里插入图片描述

改变图片的默认尺寸

这里使用的matplotlib的版本是3.4.0。 仅改变figure的尺寸,这里缩小一倍:

from mpl_toolkits.axes_grid1 import host_subplot from mpl_toolkits import axisartist import matplotlib import matplotlib.pyplot as plt fig_width = 8.26 fig_height = 8.77 width = fig_width / 2.54 #3.25英寸 height = fig_height / 2.54#3.45 fig=plt.figure(figsize=(width,height)) print(fig) host = host_subplot(111, axes_class=axisartist.Axes) fig=plt.gcf() print(fig) plt.subplots_adjust(right=0.75) par1 = host.twinx() par2 = host.twinx() par2.axis["right"] = par2.new_fixed_axis(loc="right", offset=(60, 0)) par1.axis["right"].toggle(all=True) par2.axis["right"].toggle(all=True) p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density") p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature") p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity") host.set_xlim(0, 2) host.set_ylim(0, 2) par1.set_ylim(0, 4) par2.set_ylim(1, 65) host.set_xlabel("Distance") host.set_ylabel("Density") par1.set_ylabel("Temperature") par2.set_ylabel("Velocity") host.legend() host.axis["left"].label.set_color(p1.get_color()) par1.axis["right"].label.set_color(p2.get_color()) par2.axis["right"].label.set_color(p3.get_color()) fig=plt.gcf() print(fig) plt.savefig("demo.jpg",dpi=100) fig=plt.gcf() print(fig) plt.show() fig=plt.gcf() print(fig)

控制台打印出的结果:

Backend Qt5Agg is interactive backend. Turning interactive mode on. Figure(325x345) Figure(325x345) Figure(325x345) Figure(325x345) Figure(325x345)

可以看到由于show指定的 dpi 是 100,而屏幕显示一般ppi就是100.而绘图的大小是 3.25*3.45 英寸。所以占屏幕像素的大小是 325*345.

这里的图形如下: 在这里插入图片描述 这里的一些细节就没有显示全,**说明我们改变图片大小时,有些元素是不能等比例缩放的。**如果要显示全最简单的就是增加图片的尺寸。如果真的对图片大小有限制,那么就得对绘图元素的大小进行改变。如果这里的多副y轴的参数。 另外有一点非常重要,就是绘图内容的合理布局需要给它提供合理的尺寸。这个合理的尺寸可以通过手动调节show()弹出窗口,然后测量窗口的尺寸,将其尺寸更新到figure里面,比如如窗口1000*800像素,显示的图形比较合理,那么就可以确定绘图的尺寸为(1000/100,800/1000),即(10,6).

改变matplotlib的show的dpi

这里使用的matplotlib的版本是3.4.0。show()的dpi设定为600.

from mpl_toolkits.axes_grid1 import host_subplot from mpl_toolkits import axisartist import matplotlib matplotlib.use("Qt5Agg") import matplotlib.pyplot as plt fig_width = 8.26 fig_height = 8.77 width = fig_width / 2.54 height = fig_height / 2.54 fig=plt.figure(figsize=(6.4,4.8),dpi=600) print(fig) host = host_subplot(111, axes_class=axisartist.Axes) fig=plt.gcf() print(fig) plt.subplots_adjust(right=0.75) par1 = host.twinx() par2 = host.twinx() par2.axis["right"] = par2.new_fixed_axis(loc="right", offset=(60, 0)) par1.axis["right"].toggle(all=True) par2.axis["right"].toggle(all=True) p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density") p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature") p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity") host.set_xlim(0, 2) host.set_ylim(0, 2) par1.set_ylim(0, 4) par2.set_ylim(1, 65) font2 = {'family' : 'Times New Roman', 'weight' : 'normal', 'fontsize' : 30, } # 对于这个AxesHostAxesSubplot,这样设定label是无效的。 host.set_xlabel("Distance",fontdict=font2) host.set_ylabel("Density") par1.set_ylabel("Temperature") par2.set_ylabel("Velocity") host.legend() host.axis["left"].label.set_color(p1.get_color()) # 对于这个AxesHostAxesSubplot设定标签的大小,似乎只能用这种方法? # host.axis["left"].label.set_fontsize(30) par1.axis["right"].label.set_color(p2.get_color()) par2.axis["right"].label.set_color(p3.get_color()) fig=plt.gcf() print(fig) plt.savefig("demo.jpg") fig=plt.gcf() print(fig) fig.show() fig=plt.gcf() print(fig)

控制台输出:

Backend Qt5Agg is interactive backend. Turning interactive mode on. Figure(3290x1015) Figure(3290x1015) Figure(3290x1015) Figure(3290x1015) Figure(3290x1015)

这里可以看到QtAgg的像素的垂直最大值就1050.再大就会被截断。显示的图如下:

在这里插入图片描述再查看保存的图片: 在这里插入图片描述保存的图片也受到了影响

不同backend的影响

在matplotlib 3.4.0版本上,换用TkAgg作为show的backend,并再次运行上节代码:

控制台输出为

Backend TkAgg is interactive backend. Turning interactive mode on. Figure(3840x2880) Figure(3840x2880) Figure(3840x2880) Figure(3840x2880) Figure(3840x2880)

此时显示完整的超大图片。但是由于电脑屏幕的限制,窗口垂直方向上也不能显示完全。 在这里插入图片描述 但保存的图片不受任何的影响。

在这里插入图片描述这里可以看到TkAgg比Qt5Agg好不少,但是show()这个函数没必要设定dpi,不然会改变图片的比例以及显示质量。

改变matplotlib的showfig的dpi

这里使用的matplotlib的版本是3.4.0。

from mpl_toolkits.axes_grid1 import host_subplot from mpl_toolkits import axisartist import matplotlib import matplotlib.pyplot as plt fig_width = 8.26 fig_height = 8.77 width = fig_width / 2.54 height = fig_height / 2.54 fig=plt.figure(figsize=(6.4,4.8)) print(fig) host = host_subplot(111, axes_class=axisartist.Axes) fig=plt.gcf() print(fig) plt.subplots_adjust(right=0.75) par1 = host.twinx() par2 = host.twinx() par2.axis["right"] = par2.new_fixed_axis(loc="right", offset=(60, 0)) par1.axis["right"].toggle(all=True) par2.axis["right"].toggle(all=True) p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density") p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature") p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity") host.set_xlim(0, 2) host.set_ylim(0, 2) par1.set_ylim(0, 4) par2.set_ylim(1, 65) host.set_xlabel("Distance") host.set_ylabel("Density") par1.set_ylabel("Temperature") par2.set_ylabel("Velocity") host.legend() host.axis["left"].label.set_color(p1.get_color()) par1.axis["right"].label.set_color(p2.get_color()) par2.axis["right"].label.set_color(p3.get_color()) fig=plt.gcf() print(fig) plt.savefig("demo.jpg",dpi=600) # 一般论文出图dpi为600就不错了 fig=plt.gcf() print(fig) plt.show() fig=plt.gcf() print(fig)

关于 fig 的控制台输出:

Backend Qt5Agg is interactive backend. Turning interactive mode on. Figure(640x480) Figure(640x480) Figure(640x480) Figure(640x480) Figure(640x480)

输出demo.jpg的信息: 在这里插入图片描述可以看到尺寸增加到了 3840x2800,恰好是 640*6 与 480*6

再 win 自带的画图工具里打开 demo.jpg,然后再调整回原来的大小,跟 show 图形的对比是一致的:

在这里插入图片描述到这里就能完成高dpi的出图的。但是如果你的python版本是3.6,那不能升级matplotlib为3.4.0以上的版本。你使用showfig会出现问题的。

不同版本matplotlib的showfig

如果是matplotlib的版本是3.3.4,运行上一节代码,那么这里大概率就出错了,3.3.4的控制台信息为:

Backend Qt5Agg is interactive backend. Turning interactive mode on. Figure(640x480) Figure(640x480) Figure(640x480) Figure(106.667x80) Figure(106.667x80)

show的图片十分诡异:

在这里插入图片描述 保存的图片:

在这里插入图片描述

这里暴露了 matplotlib版本对出图质量的影响。3.3.4版本的savefig的dpi设定会影响到show()。即使这里切换到TkAgg也一样。那么就只能切换到Agg的backend.

低版本matplotlib使用Agg作为backend提高出图质量 from mpl_toolkits.axes_grid1 import host_subplot from mpl_toolkits import axisartist import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt fig_width = 8.26 fig_height = 8.77 width = fig_width / 2.54 height = fig_height / 2.54 fig=plt.figure(figsize=(6.4,4.8)) print(fig) host = host_subplot(111, axes_class=axisartist.Axes) fig=plt.gcf() print(fig) plt.subplots_adjust(right=0.75) par1 = host.twinx() par2 = host.twinx() par2.axis["right"] = par2.new_fixed_axis(loc="right", offset=(60, 0)) par1.axis["right"].toggle(all=True) par2.axis["right"].toggle(all=True) p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density") p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature") p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity") host.set_xlim(0, 2) host.set_ylim(0, 2) par1.set_ylim(0, 4) par2.set_ylim(1, 65) font2 = {'family' : 'Times New Roman', 'weight' : 'normal', 'fontsize' : 30, } # 对于这个AxesHostAxesSubplot,这样设定label是无效的。 host.set_xlabel("Distance",fontdict=font2) host.set_ylabel("Density") par1.set_ylabel("Temperature") par2.set_ylabel("Velocity") host.legend() host.axis["left"].label.set_color(p1.get_color()) # 对于这个AxesHostAxesSubplot设定标签的大小,似乎只能用这种方法? # host.axis["left"].label.set_fontsize(30) par1.axis["right"].label.set_color(p2.get_color()) par2.axis["right"].label.set_color(p3.get_color()) fig=plt.gcf() print(fig) plt.savefig("demo.jpg",dpi=600) fig=plt.gcf() print(fig) fig.show() fig=plt.gcf() print(fig)

控制台输出:

Figure(640x480) Figure(640x480) Figure(640x480) Figure(640x480) demo_host_subplot_raw.py:68: UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure. fig.show() Figure(640x480)

这里可以看到Agg的backend是不支持show方法的。但是保存的图片却没有任何的问题: 在这里插入图片描述 在这里插入图片描述

其他的情况

在进行二维和三维混合出图的时候,也发现了一个问题,就是我们show()以及我们保存的图片的像素大小跟指定的大小有偏差,即使我们是采用Agg作为backend,也不能解决这个问题。那么最简单的解决方法,就是视情况多给一些图片尺寸或者少给图片一些尺寸,进行微调。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有