fig = plt.figure(figsize=(15,10))
不能改变其dpi设定。show()
方法弹出的图像展示窗口尺寸,选出自己满意的尺寸。如发现窗口1000*800像素,显示的图形比较合理,那么就可以确定绘图的尺寸为(1000/100,800/1000),即(10,6).savefig()
时,传入要保存的图片的dpi即可,如dpi=600
。保存图形时会自动扩大图形像素大小。backend
。TkAgg
比QtAgg
好,无交互窗口的Agg
出图比TkAgg
和QtAgg
更好。3.3.4
的matplotlib的savefig
和show
会相互影响,出现不可预测的问题。升高或者降低版本能解决问题。原创不易,如果本文对您有帮助的话,还请点赞收藏~
show()
的dpi,我更倾向于理解为它是一种dpi,指定100即可,太高在屏幕上还要进行扩大,并不能提高显示质量。这里使用的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的版本是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.再大就会被截断。显示的图如下:
在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的版本是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的版本是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.
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,也不能解决这个问题。那么最简单的解决方法,就是视情况多给一些图片尺寸或者少给图片一些尺寸,进行微调。