Pyplot imshow设置长宽比时不显示正方形像素

时间:2019-01-16 11:23:01

标签: python matplotlib pixel aspect-ratio imshow

使用Pyplot imshow从称为ndarray的numpy data绘制图像时遇到一些麻烦,同时保持其纵横比和方形像素不变。 ndarray的形状为(112, 2182)。这是我正在使用的代码:

import matplotlib as mpl
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np

mpl.use('Agg')

import matplotlib.pyplot as plt

data = np.random.random_sample((112, 2182))
plt.figure(figsize=(25, 3.5))
plt.subplots_adjust(left=0.1, right=0.9)

ax = plt.subplot(111)
plt.axis('off')
plt.title('Title', fontweight='bold', y=1.15)

im = ax.imshow(data)

# Add same-width colorbar to the bottom of the image
divider = make_axes_locatable(ax)
cax = divider.append_axes("bottom", size="25%", pad=0.3)
cbar = plt.colorbar(im, orientation="horizontal", cax=cax)

# Save image
plt.savefig('image.pdf', dpi=1000, format=pdf)

我认为通过使用ndarray的形状设置外观,图像将显示正方形像素。但是,该图像似乎保持长宽比,但像素不是正方形,如在缩放图像中所见(抱歉,我仍然无法发布图像):

zoomed plot
whole plot

这些输出与我使用im = ax.imshow(data)而没有aspect参数时得到的输出相同。我手动计算了整个图的y轴上的像素,其中有112个,因此这与像素分组无关。有关如何解决此问题的任何想法?

编辑:我正在绘制的图像还将具有一个颜色条和一个标题。此外,我需要能够将其保存为pdf文件。我上传的缩放图是pdf查看器中缩放图的屏幕截图。

3 个答案:

答案 0 :(得分:0)

文档说aspect参数可以是float或

  

'等于':确保宽高比为1。像素将为正方形(除非   使用以下命令在数据坐标中明确将像素大小设为非正方形   范围)。

     

'auto':轴保持固定,并且调整了长宽比,以便   数据适合轴。通常,这将导致   非正方形像素。

因此,您要寻找1.0的宽高比。给定根据数组的形状计算出的值,则不会获得上面显示的输出。 正如@ImportanceOfBeingErnest指出,aspect='equal'是默认设置,因此它很容易

im = ax.imshow(data)

答案 1 :(得分:0)

如果您使用ax.imshow(data),则会自动获得正方形像素。相反,如果将纵横比设置为1 / "equal"以外的其他值,则不会得到正方形像素。但是,这与问题中观察到的效果无关。

“缩放的图像”中的问题在于数据像素的大小约为实际屏幕像素的大小。因此,图像像素的大小可能相差一个屏幕像素。解决此问题的方法是保存一个图形,以使一个图像像素恰好是一个屏幕像素,或者是该像素的任何倍数。

在这种情况下,这就像

data = np.random.random_sample((2182, 112))
plt.imsave("filename.png", data)

答案 2 :(得分:0)

您需要使用imshow选项重新调整像素的大小:形状和范围:

import numpy as np
import matplotlib.pyplot as plt

shape = (112, 2182)
extent = [0, 112, 0, 2182]

data = np.random.random_sample(shape)

plt.figure(figsize=(5, 3.5))

ax = plt.subplot(111)
plt.axis('off')

dx = (extent[1] - extent[0]) / shape[1]
dy = (extent[3] - extent[2]) / shape[0]
dx_dy = dx/dy

im = ax.imshow(data, extent=extent, aspect=dx_dy)
plt.show()