ngo*_*aum 77 python matplotlib imshow
我正在编写一个软件系统,通过3D数据集可视化切片和投影.我正在使用matplotlib并专门imshow用于可视化我从分析代码中获取的图像缓冲区.
由于我想用绘图轴注释图像,我使用extent关键字imshow提供将图像缓冲区像素坐标映射到数据空间坐标系.
不幸的是,matplotlib不了解单位.说(以一个人为的例子)我想要绘制尺寸为的图像1000 m X 1 km.在这种情况下,范围将是类似的[0, 1000, 0, 1].即使图像阵列是方形的,由于extent关键字隐含的纵横比为1000,因此得到的绘图轴也具有1000的纵横比.
是否可以强制绘制宽高比,同时仍然使用extent关键字保留自动生成的主要刻度线和标签?
Joe*_*ton 131
您可以通过手动设置图像的方面(或通过让它自动缩放以填充图形的范围)来实现.
默认情况下,imshow将绘图的方面设置为1,因为这通常是人们对图像数据的期望.
在您的情况下,您可以执行以下操作:
import matplotlib.pyplot as plt
import numpy as np
grid = np.random.random((10,10))
fig, (ax1, ax2, ax3) = plt.subplots(nrows=3, figsize=(6,10))
ax1.imshow(grid, extent=[0,100,0,1])
ax1.set_title('Default')
ax2.imshow(grid, extent=[0,100,0,1], aspect='auto')
ax2.set_title('Auto-scaled Aspect')
ax3.imshow(grid, extent=[0,100,0,1], aspect=100)
ax3.set_title('Manually Set Aspect')
plt.tight_layout()
plt.show()
Run Code Online (Sandbox Code Playgroud)

从plt.imshow()官方指南中,我们知道 aspect 控制轴的纵横比。用我的话来说,方面就是 x unit和 y unit的比率。大多数情况下,我们希望将其保留为 1,因为我们不想无意中扭曲数字。然而,确实存在我们需要指定aspect一个不是1的值的情况。提问者提供了一个很好的例子,x轴和y轴可能有不同的物理单位。让我们假设 x 以 km 为单位,y 以 m 为单位。因此,对于 10x10 数据,范围应为 [0,10km,0,10m] = [0, 10000m, 0, 10m]。在这种情况下,如果我们继续使用默认的 aspect=1,图形的质量是非常糟糕的。因此,我们可以指定 aspect = 1000 来优化我们的图形。以下代码说明了此方法。
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
rng=np.random.RandomState(0)
data=rng.randn(10,10)
plt.imshow(data, origin = 'lower', extent = [0, 10000, 0, 10], aspect = 1000)
Run Code Online (Sandbox Code Playgroud)
尽管如此,我认为有一个替代方案可以满足提问者的需求。我们可以将范围设置为 [0,10,0,10] 并添加额外的 xy 轴标签来表示单位。代码如下。
plt.imshow(data, origin = 'lower', extent = [0, 10, 0, 10])
plt.xlabel('km')
plt.ylabel('m')
Run Code Online (Sandbox Code Playgroud)
为了得到一个正确的数字,我们应该时刻牢记x_max-x_min = x_res * data.shape[1]和y_max - y_min = y_res * data.shape[0],在哪里extent = [x_min, x_max, y_min, y_max]。默认情况下,aspect = 1,表示单位像素为正方形。此默认行为也适用于具有不同值的 x_res 和 y_res。扩展前面的例子,让我们假设 x_res 是 1.5 而 y_res 是 1。因此范围应该等于 [0,15,0,10]。使用默认方面,我们可以拥有矩形颜色像素,而单位像素仍然是正方形!
plt.imshow(data, origin = 'lower', extent = [0, 15, 0, 10])
# Or we have similar x_max and y_max but different data.shape, leading to different color pixel res.
data=rng.randn(10,5)
plt.imshow(data, origin = 'lower', extent = [0, 5, 0, 5])
Run Code Online (Sandbox Code Playgroud)
彩色像素的方面是x_res / y_res。将其方面设置为单位像素的方面(即aspect = x_res / y_res = ((x_max - x_min) / data.shape[1]) / ((y_max - y_min) / data.shape[0]))将始终给出方形颜色像素。我们可以改变 aspect = 1.5,使 x 轴单位是 y 轴单位的 1.5 倍,从而得到正方形彩色像素和正方形整图但矩形像素单位。显然,它通常不被接受。
data=rng.randn(10,10)
plt.imshow(data, origin = 'lower', extent = [0, 15, 0, 10], aspect = 1.5)
Run Code Online (Sandbox Code Playgroud)
最不希望出现的情况是将 aspect 设置为任意值,例如 1.2,这将导致既不是方形单位像素也不是方形彩色像素。
plt.imshow(data, origin = 'lower', extent = [0, 15, 0, 10], aspect = 1.2)
Run Code Online (Sandbox Code Playgroud)
长话短说,设置正确的范围并让 matplotlib 为我们做剩下的事情总是足够的(即使 x_res!=y_res)!仅在必须时更改方面。
| 归档时间: |
|
| 查看次数: |
96156 次 |
| 最近记录: |