Нет никаких расхождений, вы просто устанавливаете галочки вручную для значений, которые не являются тем, чем они являются на самом деле.
Обратите внимание, что ваш LABELS
равен просто range(13)
, в то время как ваш фактическийположения тиков (ticks
) не варьируются от 0 до 12.
Итак, вы вручную помечаете верхний тик, который имеет позицию 10,6, как 12!
Попробуйтевычеркнув строку cb.ax.set_yticklabels(map(str, LABELS))
, и вы поймете, что я имею в виду (Кроме того, matplotlib автоматически приведёт их к строкам. Нет причин вызывать map(str, LABELS)
).
Возможно, вместо использования статического наборачисел в качестве меток, вы должны просто конвертировать ваши фактические места галочки в метки?Что-то вроде [round(tick) for tick in ticks]
?
Редактировать: Извините, это звучало странно, чем я хотел ... Я не хотел, чтобы это звучало так!:)
Edit2 : в ответ на обновленный вопрос, да, imshow
определяет диапазон автоматически из минимального и максимального значений ввода.(Я в замешательстве ... Что еще это могло бы сделать?)
Если вы хотите прямое сопоставление цветов без интерполяции, тогда используйте одну из дискретных цветовых карт, а не LinearSegmentedColormap
.Однако проще всего вручную установить пределы для одного из LinearSegmentedColormap
с matplotlib (что и есть matplotlib.cm.spectral
).
Если вы хотите вручную установить диапазон используемого цветового отображения, просто вызовите set_clim([0,12])
для объекта coloraxis, который возвращает imshow
.
Например
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
with open('temp.pgm') as infile:
header, nrows, ncols = [infile.readline().strip() for _ in range(3)]
data = np.loadtxt(infile).astype(np.uint8)
cmap = mpl.cm.get_cmap('spectral', 13)
cax = plt.imshow(data, cmap, interpolation='nearest')
cax.set_clim([0,13])
cbar = plt.colorbar(cax, ticks=np.arange(0.5, 13, 1.0))
cbar.ax.set_yticklabels(range(13))
plt.show()