如何在matplotlib中更改imshow的比例而不拉伸图像?

9
我希望使用imshow进行绘图,方式与此处的第二个示例类似 http://www.scipy.org/Plotting_Tutorial,但需要重新定义轴的比例尺。同时,我希望在这个过程中图像保持不动!
示例代码:
from scipy import *
from pylab import *

# Creating the grid of coordinates x,y 
x,y = ogrid[-1.:1.:.01, -1.:1.:.01]

z = 3*y*(3*x**2-y**2)/4 + .5*cos(6*pi * sqrt(x**2 +y**2) + arctan2(x,y))

hold(True)
# Creating image
imshow(z, origin='lower', extent=[-1,1,-1,1])

xlabel('x')
ylabel('y')
title('A spiral !')

# Adding a line plot slicing the z matrix just for fun. 
plot(x[:], z[50, :])

show()

如果我将范围修改为更宽,例如:
imshow(z, origin='lower', extent=[-4,4,-1,1])

然后生成的图像被拉伸。但我想做的只是将刻度与我的数据相一致。我知道可以使用pcolor来保存X和Y数据,但这会带来其他影响。
我找到了这个答案,它允许我手动重新设置所有刻度: 如何在matplotlib中转换(或缩放)轴值并重新定义刻度频率? 但那似乎有些过度。
有没有办法仅更改标签显示的范围?
2个回答

10

使用help(imshow)可以找到aspect参数,经过一些实验,当以如下方式使用时,它似乎能够达到你想要的效果(一个螺旋的正方形图像,但x轴比例尺在-4到4之间,y轴在-1到1之间):

imshow(z, origin='lower', extent=[-4,4,-1,1], aspect=4)

但是现在你的plot仍然从-1到1,所以你需要修改它......

plot(x[:]*4, z[50, :])

我认为,当你需要修改多个元素时,仅使用一行勾选标签来重新标记并不过分:
xticks(xticks()[0], [str(t*4) for t in xticks()[0]])

Aspect对于我的使用情况是一个很好的解决方案,因为我那里没有绘图。而且你比我更优雅地解决了xticks的问题。谢谢! - ubershmekel

1
我建议不要像接受的答案那样使用aspect关键字来完成此任务。让图像决定您的Axes的纵横比,并通过缩放因子简单地将图像的extent乘以。如果您不这样做,您将被迫缩放所有后续添加的艺术家。
下面的代码片段显示了具有默认行为的图像:将1个数据单位分配给1个像素。
image:np.ndarray = ... # We will assume that you already loaded an image.

fig, ax = plt.subplots()
fig.show()
ax.imshow(image, cmap="gray", origin="lower")
ax.autoscale(False)
fig.canvas.draw()

这段代码可以对图像进行缩放。

SCALE = 5e-6/105

image:np.ndarray = ... # We will assume that you already loaded an image.

fig, ax = plt.subplots()
fig.show()
image_artist = ax.imshow(image, cmap="gray", origin="lower")
image_artist.set_extent(np.array(image_artist.get_extent())*SCALE)
ax.autoscale(False)
fig.canvas.draw()

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接