matplotlib Pyplot imshow设置纵横比时不显示方形像素

pkwftd7m  于 2023-05-07  发布在  其他
关注(0)|答案(4)|浏览(227)

我在使用Pyplot imshow绘制一个名为data的numpy ndarray的图像时遇到了一些麻烦,因为它既保持了长宽比,又保持了方形像素。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查看器中放大的图的屏幕截图。

ef1yzkbh

ef1yzkbh1#

如果使用ax.imshow(data),则会自动获得方形像素。如果您将纵横比设置为1/"equal"以外的值,则不会获得方形像素。然而,这与问题中观察到的效果无关。
“缩放图像”中的问题是数据像素的大小是实际屏幕像素的数量级。因此,图像像素的大小可能与屏幕像素一样多地变化。解决这个问题的方法是保存一个图形,使得一个图像像素正好是一个屏幕像素,或者是它的任何倍数。
在这种情况下,这将是一样简单

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

4uqofj5v2#

您需要使用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()
m1m5dgzv

m1m5dgzv3#

文档说明aspect参数可以是浮点数或
'equal':确保纵横比为1。像素将是正方形的(除非使用范围在数据坐标中显式地使像素大小为非正方形)。
“自动”:轴保持固定,并调整纵横比,以便数据适合轴。通常,这将导致非正方形像素。
因此,纵横比为1.0是您正在寻找的。根据数组的形状计算出的值,不期望得到上面显示的输出。正如@ImportanceOfBeingErnest指出的那样,aspect='equal'是默认值,所以它就像

im = ax.imshow(data)
cigdeys3

cigdeys34#

我遇到了同样的问题,或者至少是一个非常相似的问题,导出的PDF文件中的一些像素是矩形的。在我看来,我不应该为我导出的PDF文件确定一个像素完美的DPI值。
引起我注意的是,在Matplotlib imshow documentation中,他们专门调用了一个interpolation参数值,该参数值在PDF和其他矢量图形后端上的作用不同:interpolation='none'。这里的警告是,在下采样图像的情况下,PDF查看器将是执行下采样的人,这可能会导致根据PDF查看器的不同而变化的行为。然而,对于上采样,它似乎对我很有效。
在左边,下面,我显示了PDF中默认插值图像的屏幕截图,在右边,我显示了相同的屏幕截图interpolation='none'

相关问题