Установка правильных ограничений с помощью imshow, если форма данных изображения изменяется - PullRequest
3 голосов
/ 15 сентября 2011

У меня есть 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) после каждого поворота, но я все еще получаю то же поведение.

1 Ответ

4 голосов
/ 16 сентября 2011

Ниже я приведу решение вашей проблемы. Метод 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()

Этот скрипт создает два изображения: Первый не повернутый: enter image description here Затем повернул: enter image description here

Я думал, что просто явный вызов set_extent сделает все, что делает resetExtent, потому что он должен регулировать пределы осей, если 'autoscle' - True. Но по какой-то неизвестной причине вызов set_extent сам по себе не делает эту работу.

...