更改 matplotlib imshow() 图形轴上的值

问题描述 投票:0回答:3

假设我有一些输入数据:

data = np.random.normal(loc=100, scale=10, size=(500,1,32))
hist = np.ones((32, 20)) # initialise hist
for z in range(32):
    hist[z], edges = np.histogram(data[:, 0, z], bins=np.arange(80, 122, 2))

我可以使用

imshow()
来绘制它:

plt.imshow(hist, cmap='Reds')

得到:

first try

但是,x 轴值与输入数据不匹配(即 100 的平均值,范围从 80 到 122)。因此,我想更改 x 轴以显示

edges
.

中的值

我试过:

ax = plt.gca()
ax.set_xlabel([80,122]) # range of values in edges
...
# this shifts the plot so that nothing is visible

ax.set_xticklabels(edges)
...
# this labels the axis but does not centre around the mean:

second try

关于如何更改轴值以反映我正在使用的输入数据的任何想法?

python numpy matplotlib plot imshow
3个回答
193
投票

如果可能的话,我会尽量避免改变

xticklabels
,否则如果你用额外的数据过度绘制你的直方图,它会变得非常混乱。

定义网格的范围可能是最好的,使用

imshow
可以通过添加
extent
关键字来完成。这样轴就会自动调整。如果你想更改标签,我会使用
set_xticks
和一些格式化程序。直接更改标签应该是最后的手段。

fig, ax = plt.subplots(figsize=(6,6))

ax.imshow(hist, cmap=plt.cm.Reds, interpolation='none', extent=[80,120,32,0])
ax.set_aspect(2) # you may also use am.imshow(..., aspect="auto") to restore the aspect ratio

enter image description here


18
投票

我遇到了类似的问题,谷歌将我发送到这篇文章。我的解决方案有点不同而且不太紧凑,但希望这对某人有用。

使用 matplotlib.pyplot.imshow 显示图像通常是显示 2D 数据的快速方法。然而,默认情况下,这会用像素数标记轴。如果您正在绘制的二维数据对应于数组 x 和 y 定义的一些统一网格,那么您可以使用 matplotlib.pyplot.xticks 和 matplotlib.pyplot.yticks 使用这些数组中的值来标记 x 和 y 轴。这些会将与实际网格数据相对应的一些标签与轴上的像素计数相关联。这样做比使用 pcolor 之类的东西要快得多。

这是对您的数据的尝试:

import matplotlib.pyplot as plt

# ... define 2D array hist as you did

plt.imshow(hist, cmap='Reds')
x = np.arange(80,122,2) # the grid to which your data corresponds
nx = x.shape[0]
no_labels = 7 # how many labels to see on axis x
step_x = int(nx / (no_labels - 1)) # step between consecutive labels
x_positions = np.arange(0,nx,step_x) # pixel count at label position
x_labels = x[::step_x] # labels you want to see
plt.xticks(x_positions, x_labels)
# in principle you can do the same for y, but it is not necessary in your case

0
投票

extent=
设置为某个列表时,图像将沿 x 轴和 y 轴单独拉伸以填充框。但有时,最好使用
ax.set
plt.xticks
/
plt.yticks
显式设置刻度标签(imo):

fig, ax = plt.subplots(figsize=(6,6))
ax.imshow(hist, cmap='Reds', interpolation='none', extent=[80, 120, 32, 0], aspect=2)
ax.set(xticks=np.arange(80, 122)[::10], xticklabels=np.arange(80, 122)[::10]);

由于

extent=
设置了图片大小,用它来设置刻度标签有时并不理想。例如,我们要显示一个相对较高但带有小刻度标签的图像,如下所示:

那么,

fig, ax = plt.subplots(1, figsize=(6, 6))
ax.imshow(np.arange(120)[None, :], cmap='Reds', extent=[0, 120, 1, 0]);

生产

但是

fig, ax = plt.subplots(1, figsize=(6, 6))
ax.imshow(np.arange(120)[None, :], cmap='Reds', extent=[0, 120, 10, 0]);
ax.set(xticks=np.linspace(0, 120, 7), xticklabels=np.arange(0, 121, 20), yticks=[0, 10], yticklabels=[0, 1]);

产生正确的输出。这是因为

extent=
被设置为较大的值,但刻度标签设置为较小的值,以便图像具有所需的标签。

注意

ax.get_xticks()
ax.get_yticks()
是了解默认(或其他)刻度位置的有用方法,
ax.get_xlim()
ax.get_ylim()
是了解轴限制的有用方法。


即使在OP使用的方法中,没有任何

extent=
ax.get_xlim()
返回
(-1.0, 19.5)
。由于 x-tick 位置范围已经设置为这样,它可用于将 x-tick 标签设置为其他内容;只需将 xticks 设置为该范围内的一些值,然后将任何值分配给 xticklabels。所以下面渲染了想要的图像。

fig, ax = plt.subplots(figsize=(6,6))
ax.imshow(hist, cmap='Reds', interpolation='none', aspect=2)
ax.set(xticks=np.arange(-1, 20, 5), xticklabels=np.arange(80, 122, 10));
© www.soinside.com 2019 - 2024. All rights reserved.