如果图像数据形状发生变化,使用 imshow 设置正确的限制

发布于 2024-12-04 22:09:32 字数 936 浏览 0 评论 0原文

我有一个 3D 数组,其中前两个维度是空间维度,所以说 (x,y)。第三维包含点特定信息。

print H.shape  # --> (200, 480, 640)  spatial extents (200,480)

现在,通过选择三维中的某个平面,我可以显示一个图像,

imdat = H[:,:,100]    # shape (200, 480)
img = ax.imshow(imdat, cmap='jet',vmin=imdat.min(),vmax=imdat.max(), animated=True, aspect='equal')

我现在想要旋转立方体,以便我从 (x,y) 切换到 (y,x)。

    H = np.rot90(H)          # could also use H.swapaxes(0,1) or H.transpose((1,0,2)) 
    print H.shape    # --> (480, 200, 640)

现在,当我打电话时:

imdat = H[:,:,100]   # shape (480,200)
img.set_data(imdat)
ax.relim()
ax.autoscale_view(tight=True)

我的行为很奇怪。沿行的图像显示数据直到第 200 行,然后直到 y 轴末端 (480) 为止都是黑色的。 x 轴从 0 延伸到 200,显示旋转后的数据。现在,再旋转 90 度,图像会正确显示(当然只是旋转 180 度)

在我看来,旋转数据后,轴限制(或图像范围?)或某些内容无法正确刷新。有人可以帮忙吗?

PS:为了沉迷于糟糕的黑客行为,我还尝试在每次旋转后重新生成一个新图像(通过调用 ax.imshow),但我仍然得到相同的行为。

I have a 3D array, of which the first two dimensions are spatial, so say (x,y). The third dimension contains point-specific information.

print H.shape  # --> (200, 480, 640)  spatial extents (200,480)

Now, by selecting a certain plane in the third dimension, I can display an image with

imdat = H[:,:,100]    # shape (200, 480)
img = ax.imshow(imdat, cmap='jet',vmin=imdat.min(),vmax=imdat.max(), animated=True, aspect='equal')

I want to now rotate the cube, so that I switch from (x,y) to (y,x).

    H = np.rot90(H)          # could also use H.swapaxes(0,1) or H.transpose((1,0,2)) 
    print H.shape    # --> (480, 200, 640)

Now, when I call:

imdat = H[:,:,100]   # shape (480,200)
img.set_data(imdat)
ax.relim()
ax.autoscale_view(tight=True)

I get weird behavior. The image along the rows displays the data till 200th row, and then it is black until the end of the y-axis (480). The x-axis extends from 0 to 200 and shows the rotated data. Now on, another rotation by 90-degrees, the image displays correctly (just rotated 180 degrees of course)

It seems to me like after rotating the data, the axis limits, (or image extents?) or something is not refreshing correctly. Can somebody help?

PS: to indulge in bad hacking, I also tried to regenerate a new image (by calling ax.imshow) after each rotation, but I still get the same behavior.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光暖心i 2024-12-11 22:09:32

下面我提供了您的问题的解决方案。 resetExtent 方法使用数据和图像将范围显式设置为所需值。希望我正确地模拟了预期的结果。

import matplotlib.pyplot as plt
import numpy as np

def resetExtent(data,im):
    """
    Using the data and axes from an AxesImage, im, force the extent and 
    axis values to match shape of data.
    """
    ax = im.get_axes()
    dataShape = data.shape

    if im.origin == 'upper':
        im.set_extent((-0.5,dataShape[0]-.5,dataShape[1]-.5,-.5))
        ax.set_xlim((-0.5,dataShape[0]-.5))
        ax.set_ylim((dataShape[1]-.5,-.5))
    else:
        im.set_extent((-0.5,dataShape[0]-.5,-.5,dataShape[1]-.5))
        ax.set_xlim((-0.5,dataShape[0]-.5))
        ax.set_ylim((-.5,dataShape[1]-.5))

def main():
    fig = plt.gcf()
    ax = fig.gca()

    H = np.zeros((200,480,10))
    # make distinguishing corner of data
    H[100:,...] = 1
    H[100:,240:,:] = 2

    imdat = H[:,:,5]
    datShape = imdat.shape

    im = ax.imshow(imdat,cmap='jet',vmin=imdat.min(),
                    vmax=imdat.max(),animated=True,
                    aspect='equal',
                    #                origin='lower'
                    )

    resetExtent(imdat,im)

    fig.savefig("img1.png")

    H = np.rot90(H)

    imdat = H[:,:,0]
    im.set_data(imdat)
    resetExtent(imdat,im)

    fig.savefig("img2.png")

if __name__ == '__main__':
  main()

该脚本生成两个图像:
首先未旋转:
在此处输入图像描述
然后旋转:
在此处输入图像描述

我认为只需显式调用 set_extent 即可完成所有操作 resetExtent 确实如此,因为如果 'autoscle' 为 True,它应该调整轴限制。但由于某种未知的原因,单独调用 set_extent 并不能完成这项工作。

Below I include a solution to your problem. The method resetExtent uses the data and the image to explicitly set the extent to the desired values. Hopefully I correctly emulated the intended outcome.

import matplotlib.pyplot as plt
import numpy as np

def resetExtent(data,im):
    """
    Using the data and axes from an AxesImage, im, force the extent and 
    axis values to match shape of data.
    """
    ax = im.get_axes()
    dataShape = data.shape

    if im.origin == 'upper':
        im.set_extent((-0.5,dataShape[0]-.5,dataShape[1]-.5,-.5))
        ax.set_xlim((-0.5,dataShape[0]-.5))
        ax.set_ylim((dataShape[1]-.5,-.5))
    else:
        im.set_extent((-0.5,dataShape[0]-.5,-.5,dataShape[1]-.5))
        ax.set_xlim((-0.5,dataShape[0]-.5))
        ax.set_ylim((-.5,dataShape[1]-.5))

def main():
    fig = plt.gcf()
    ax = fig.gca()

    H = np.zeros((200,480,10))
    # make distinguishing corner of data
    H[100:,...] = 1
    H[100:,240:,:] = 2

    imdat = H[:,:,5]
    datShape = imdat.shape

    im = ax.imshow(imdat,cmap='jet',vmin=imdat.min(),
                    vmax=imdat.max(),animated=True,
                    aspect='equal',
                    #                origin='lower'
                    )

    resetExtent(imdat,im)

    fig.savefig("img1.png")

    H = np.rot90(H)

    imdat = H[:,:,0]
    im.set_data(imdat)
    resetExtent(imdat,im)

    fig.savefig("img2.png")

if __name__ == '__main__':
  main()

This script produces two images:
First un-rotated:
enter image description here
Then rotated:
enter image description here

I thought just explicitly calling set_extent would do everything resetExtent does, because it should adjust the axes limits if 'autoscle' is True. But for some unknown reason, calling set_extent alone does not do the job.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文