matplotlib - 在 matplotlib pyplot imshow() 和 savefig()的完全分辨率下,python 打印?

我有一个中等大小的数组(例如1500x3000),它是一个图像,我想按比例绘制。然而垂直和水平的尺度不同,

下面是一个模拟我的问题的代码。


import numpy as np


import matplotlib.pyplot as plt


import matplotlib.colors



R, C = 1500, 3000


DATA = np.random.random((R, C))


DATA[::2, :] *= -1 # make every other line negative


Yi, Xi = 1, 10 # increment


CMP = 'seismic'


ImageFormat ='pdf'


Name = 'Image'



DataRange = (np.absolute(DATA)).max() # I want my data centred on 0


EXTENT = [0, Xi*C, 0 ,Yi*R]


NORM = matplotlib.colors.Normalize(vmin =-DataRange, vmax= DataRange, clip =True)



for i in range(1,4):


 Fig=plt.figure(figsize=(45, 10), dpi = 100*i, tight_layout=True)


 Fig.suptitle(Name+str(i)+'00DPI')


 ax = Fig.add_subplot(1, 1, 1)


 Plot = ax.imshow(DATA, cmap=plt.get_cmap(CMP), norm = NORM, extent = EXTENT, aspect = 1, interpolation='none') 


 ax.set_xlabel('metres')


 ax.set_ylabel('metres')


 Fig.savefig(Name+str(i)+'00DPI.'+ImageFormat, format = ImageFormat, dpi = Fig.dpi)


plt.close()



时间:

我运行了您的示例,缩放后,一切在matplotlib中看起来都不错:无论分辨率如何,结果都是一样的,我每轴单位看到一个像素。此外,尝试使用较小的数组,pdf(或其他格式)也可以很好地工作。

然后你必须增加dpi,并且设置interpolation='none'(如果分辨率设置好,不重要),

我不知道以下方法是否是最好的方法,matplotlib中可能有更合适的方法和属性,但是我会尝试计算最佳dpi:


vsize=ax.get_position().size[1] #fraction of figure occupied by axes


axesdpi= int((Fig.get_size_inches()[1]*vsize)/R) #(or Yi*R according to what you want to do)



然后你的代码(减少到第一个循环)变成:


import numpy as np


import matplotlib.pyplot as plt


import matplotlib.colors



R, C = 1500, 3000


DATA = np.random.random((R, C))


DATA[::2, :] *= -1 # make every other line negative


Yi, Xi = 1, 10 # increment


CMP = 'seismic'


ImageFormat ='pdf'


Name = 'Image'



DataRange = (np.absolute(DATA)).max() # I want my data centred on 0


EXTENT = [0, Xi*C, 0 ,Yi*R]


NORM = matplotlib.colors.Normalize(vmin =-DataRange, vmax= DataRange, clip =True)



for i in (1,):


 print i 


 Fig=plt.figure(figsize=(45, 10), dpi = 100*i, tight_layout=True)


 Fig.suptitle(Name+str(i)+'00DPI')


 ax = Fig.add_subplot(1, 1, 1)


 Plot = ax.imshow(DATA, cmap=plt.get_cmap(CMP), norm = NORM, extent = EXTENT, aspect = 1, interpolation='none') 


 ax.set_xlabel('metres')


 ax.set_ylabel('metres')


 vsize=ax.get_position().size[1] #fraction of figure occupied by axes


 axesdpi= int((Fig.get_size_inches()[1]*vsize)/R) #(or Yi*R according to what you want to do)


 Fig.savefig(Name+str(axesdpi)+'DPI.'+ImageFormat, format = ImageFormat, dpi = axesdpi)


 #plt.close()



这对我来说是合理的。

我认为您想要做的是有效地绘制每列10次,因此您获得的图像为1500 x 30000像素。要执行此操作,请使用你自己的所有代码,可以使用np.repeat执行以下操作:


import numpy as np


import matplotlib.pyplot as plt


import matplotlib.colors



R, C = 1500, 3000


DATA = np.random.random((R, C))


DATA[::2, :] = 0 # make every other line plain white


Yi, Xi = 1, 10 # increment


DATA = np.repeat(DATA, Xi, axis=1)


DATA = np.repeat(DATA, Yi)



CMP = 'seismic'


ImageFormat ='pdf'


Name = 'Image'



DataRange = (np.absolute(DATA)).max() # I want my data centred on 0


EXTENT = [0, Xi*C, 0 ,Yi*R]


NORM = matplotlib.colors.Normalize(vmin =-DataRange, vmax= DataRange, clip =True)



for i in range(1,4):


 Fig=plt.figure(figsize=(45, 10), dpi = 100*i, tight_layout=True)


 Fig.suptitle(Name+str(i)+'00DPI')


 ax = Fig.add_subplot(1, 1, 1)


 Plot = ax.imshow(DATA, cmap=plt.get_cmap(CMP), norm = NORM, extent = EXTENT, aspect = 1, interpolation='none') 


 ax.set_xlabel('metres')


 ax.set_ylabel('metres')


 Fig.savefig(Name+str(i)+'00DPI.'+ImageFormat, format = ImageFormat, dpi = Fig.dpi)


plt.close()



注意:这是一个内存密集型解决方案-可能会有更好的方法。如果不需要pdf的矢量图形输出,可以将ImageFormat变量更改为png

...