Как создать дискретную цветовую шкалу по строкам как график времени и высоты? - PullRequest
1 голос
/ 23 марта 2020

Вывод моего алгоритма дает мне определенную строку. Мне нужно визуализировать их в графике высоты-времени с цветами, определенными этими строками. Все идет нормально. Я преобразую строки в категориальные и могу свободно выбирать цвета.

num_hydrometeor = 8
ncar_cmap = cm.get_cmap('gist_ncar_r', num_hydrometeor)

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,400)
beam_height_test = beam_height_test = np.sort(np.random.choice(a,size=180))
times = pd.date_range('1/1/2020', periods = 288, 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)))

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)))

cols = []
a = pd.Series(data=test_dist_hca.flatten()).sort_values().unique()
for hc in a:
    cols.append(colors[hc])
ncar_cmap = cm.colors.ListedColormap(cols)

levels = np.unique(test_dist_hca_cat)

plt.figure(figsize=(40,10))
plt.pcolormesh(times,beam_height_test,test_dist_hca_cat,cmap=ncar_cmap,norm = cm.colors.BoundaryNorm(levels, ncolors=ncar_cmap.N, clip=False))
plt.colorbar()

plt.savefig("hmc_daily_test.png")

hmc_daily_test.png

При применении к моему реальному выводу это выглядит так:

hmc_daily_test2.png

Кто-нибудь имеет представление, что я делаю не так? Вывод алгоритма происходит из pandas DataFrame и идет так же, как и pandas .Series в минимальном примере.

1 Ответ

1 голос
/ 23 марта 2020

Чтобы узнать, что происходит, я уменьшил размеры. Я также создал точечную диаграмму, где цвета выбираются непосредственно из словаря без маршрута через .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

И соответствующий точечный график с текстовыми аннотациями:

scatter plot

Обратите внимание, что цвета и названия соответствуют. Как объясняется в pcolormesh документах , pcolormesh игнорирует последнюю строку и столбец, когда размеры X и Y не на 1 больше, чем me sh.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...