Imshow - разделен на разные размеры пикселей

Я пытаюсь получить следующее, что должно быть показано на рисунке ниже.

Предположим, для простоты у меня есть массив numpy (10x10), который я хочу построить с помощью matplotlib imshow. Условие состоит в том, чтобы иметь разные размеры пикселей, например: первые пять строк должны иметь размер 0,5 см, последние пять строк должны иметь размер 1 см. Столбцы должны иметь одинаковый размер.

Как я могу легко реализовать это? Я уже пытался это сделать, но мне это решение не нравится; в частности, у меня все еще есть белые рамки, а масштабирование ужасно.

from matplotlib import pyplot as pl
import numpy as np

data = np.arange((100))
data = np.reshape(data, (10,10))

figure, (ax1, ax2) = pl.subplots(2, 1, sharex='col')
figure.subplots_adjust(hspace=0)
data1=data[5:10,:]
ax1.imshow(data1, origin="lower", interpolation="none", aspect=0.5, extent=[-0.5,10.5,5.5,10.5], vmax=np.amax(data), vmin=np.amin(data))
ax1.set_ylim([5.5,10.5])
##
data2=data[0:5,:]
ax2.imshow(data2, origin="lower", interpolation="none", aspect=1, extent=[-0.5,10.5,-0.5,5.5], vmax=np.amax(data), vmin=np.amin(data))
ax2.set_ylim([-0.5,5.5])
pl.show()

Вывод кода Спасибо Пример для разных размеров пикселей / желаемого изображения


person pallago    schedule 01.02.2016    source источник
comment
Некрасивым решением было бы удвоить строки, которые вам нужно увеличить. Вместо массива 10*10 у вас будет массив 10*15. Но наверняка есть правильное решение   -  person CoMartel    schedule 01.02.2016
comment
Вам нужно, чтобы нумерация строк совпадала или ее можно опустить?   -  person Noel Segura Meraz    schedule 01.02.2016


Ответы (1)


Это намного проще, если вы просто используете один объект осей. Тогда и масштабирование будет работать безупречно.

Код:

from matplotlib import pyplot as plt
import numpy as np

# prepare the data
data = np.arange((100))
data = np.reshape(data, (10,10))
data1=data[0:5,:]
data2=data[5:10,:]

# create the figure and a single axis
fig, ax = plt.subplots()

# common arguments to imshow
kwargs = dict(
        origin='lower', interpolation='nearest', vmin=np.amin(data),
        vmax=np.amax(data), aspect='auto')

# draw the data
ax.imshow(data1, extent=[0, 10, 0, 5], **kwargs)
ax.imshow(data2, extent=[0, 10, 5, 7.5], **kwargs)

# optional black line between data1 and data2
ax.axhline(5, color='k')

# set the axis limits
ax.set_ylim(0, 7.5)
ax.set_xlim(0, 10)

# set the xticklabels
xticks = np.arange(0,10)
ax.set_xticks(xticks + 0.5)
ax.set_xticklabels(map(str, xticks))

# set the yticks and labels
yticks = np.concatenate((
        np.arange(0, 5) + 0.5,
        np.arange(5, 7.5, 0.5) + 0.25
        ))
ax.set_yticks(yticks)
ax.set_yticklabels(map(str, xticks))

# show the figure
plt.show()

Результат:

введите здесь описание изображения

Комментарии:

  • Я позволил себе переименовать объекты data1/2 более интуитивно понятным способом.
  • Спасибо @kazemakase за указание на необходимость адаптации осей.
person hitzg    schedule 01.02.2016
comment
Вы также можете использовать ax.set_yticks и ax.set_ytlicklabels для получения правильных меток для каждой строки пикселей. - person kazemakase; 01.02.2016
comment
Хорошая точка зрения! Или сдвиньте пределы данных на 0,5, как это сделал ОП в своем вопросе. - person hitzg; 01.02.2016
comment
Одно только смещение не сработает, так как нужно пропускать каждый второй тик в нижней части. - person kazemakase; 01.02.2016
comment
Да, ты полностью прав. Я добавлю это к ответу. - person hitzg; 01.02.2016