Чтобы узнать, что происходит, я уменьшил размеры. Я также создал точечную диаграмму, где цвета выбираются непосредственно из словаря без маршрута через .astype('category')
.
. Кажется, nan
несколько усложняет ситуацию, потому что он получает номер категории -1. Поэтому его нужно рассматривать отдельно от остальных, и нам нужны диапазоны для цветов, начинающиеся с -1
.
. Чтобы получить метки для цветовой шкалы точно в центре каждого цвета, его диапазон ( От -1 до 4 в данном случае) делится на 12 равных частей, после чего пропускается каждый четный тик.
Вот как выглядит окончательный код теста:
from matplotlib import pyplot as plt
from matplotlib import cm
import pandas as pd
import numpy as np
colors = {'AG': 'chocolate', 'IC': 'orange', 'DN': 'yellowgreen', 'OT': 'grey', 'WS': 'r', 'FZ': 'rosybrown',
'RN': 'teal', 'IP': 'cyan', np.nan: 'white'}
a = np.linspace(0, 18, 25)
beam_height_test = np.sort(np.random.choice(a, replace=False, size=10))
times = pd.date_range('1/1/2020', periods=12, freq='5min')
C = np.array(['WS', 'OT', 'FZ', np.nan, 'AG', 'IC'], dtype=object)
test_dist_hca = np.random.choice(C, size=(len(beam_height_test), len(times)))
plt.figure(figsize=(14, 7))
plt.scatter(np.tile(times, len(beam_height_test)),
np.repeat(beam_height_test, len(times)),
c=[colors[h] for h in test_dist_hca.flatten()])
for i, x in enumerate(times):
for j, y in enumerate(beam_height_test):
plt.text(x, y, test_dist_hca[j][i])
plt.show()
test_dist_hca_cat = pd.Series(data=test_dist_hca.flatten()).astype('category')
test_dist_hca_cat = test_dist_hca_cat.cat.codes
test_dist_hca_cat = test_dist_hca_cat.values
test_dist_hca_cat = test_dist_hca_cat.reshape((len(beam_height_test), len(times)))
used_colors = [colors[np.nan]]
a = pd.Series(data=test_dist_hca.flatten()).sort_values().unique()
for hc in a:
if type(hc) == str:
used_colors.append(colors[hc])
cmap = cm.colors.ListedColormap(used_colors)
plt.figure(figsize=(14, 7))
plt.pcolormesh(times, beam_height_test, test_dist_hca_cat,
cmap=cmap,
norm=plt.Normalize(vmin=-1, vmax=len(a) - 2))
cbar = plt.colorbar(ticks=np.linspace(-1, len(a) - 2, 2 * len(a), endpoint=False)[1::2])
cbar.ax.set_yticklabels(['nan'] + list(a[:-1]))
plt.show()
Вот как выглядит pcolormesh
с цветовой шкалой:
![resulting plot](https://i.stack.imgur.com/iI445.png)
И соответствующий точечный график с текстовыми аннотациями:
![scatter plot](https://i.stack.imgur.com/xp0ll.png)
Обратите внимание, что цвета и названия соответствуют. Как объясняется в pcolormesh
документах , pcolormesh
игнорирует последнюю строку и столбец, когда размеры X и Y не на 1 больше, чем me sh.