Тепловая карта Barplot & Seaborn Matplotlib: Поделиться той же осью X - PullRequest
1 голос
/ 10 февраля 2020

Я создаю участок с двумя отдельными диаграммами: один использует график в Matplotlib и тепловой карту в Seaborn. Я сталкиваюсь с проблемами, когда ось X на графике не совмещается с осью Seaborn, как показано на следующем рисунке:

enter image description here

Дальнейшее чтение здесь показывает, что оси графиков в Matploblib являются категориальными [0,1,2, x], поэтому мой код ниже объяснил это. Я использую переменную с сохраненным результатом Numpy для общего числа точек графика (переменная objects_30 в приведенном ниже коде), которая подается на обе оси x для графиков Barplot Matplotlib и Seaborn.

Любые предложения о том, как заставить ось X Matplotlib одинаково распределяться по оси X Seaborn?

Фрагмент кода участка:

objects_30pos = np.arange(len(objects_30))
ymax_pos = np.arange(len(objects_30))

heatmap_blnd = pd.DataFrame({'ENS MEMBER':'S1', 'highs':temps, 'FORECAST PERIOD':objects_30pos})
hmap_data = pd.pivot_table(heatmap_blnd, values='highs', index=['ENS MEMBER'], columns=['FORECAST PERIOD'])

run = (time + timedelta(hours=1)).strftime('%-H AM %a. %d %b. %Y')

fig, ax = plt.subplots(figsize=(14,8), sharex=True, sharey=True)
gs = gridspec.GridSpec(2, 1, height_ratios=[11, 1]) 
bar_width = 0.40

min_high = min(temps)
max_high = max(temps)
max_highhght = max_high + 5
min_highhght = min_high - 5
highheight = [x - min_highhght for x in temps]

#plt.subplot(2, 1, 1)
plt.subplot(gs[0])
rectstop = plt.bar(ymax_pos, height=highheight, width=0.60, bottom=min_highhght, color='#1e90ff', edgecolor='black', linewidth=2, zorder=3)
for rect in rectstop:
    y_value = rect.get_height()+min_highhght
    x_value = rect.get_x() + rect.get_width() / 2
    space = 2
    va = 'bottom'
    label = y_value
    plttxt = plt.annotate(label, (x_value, y_value), xytext=(0, space), textcoords="offset points", ha='center', va=va)
    plttxt.set_fontsize(12)
    plttxt.set_weight('semibold')
plt.xticks(ymax_pos, objects_30, fontsize=12)
plt.yticks(fontsize=12)
plt.yticks(fontsize=12)
plt.ylim(min_highhght,max_highhght)
if 100 in range(min_highhght,max_highhght):
    plt.axhline(y=100, color='red', linestyle='--')
if 32 in range(min_highhght,max_highhght):
    plt.axhline(y=32, color='blue', linestyle='--')
if 0 in range(min_highhght,max_highhght):
    plt.axhline(y=0, color='purple', linestyle='--')
plt.ylabel('Temperature [°F]', fontsize=12, fontweight='semibold')
plt.tick_params(axis='x', pad=10, length=10)
plt.grid(True, linestyle='--', zorder=0)

plt.title(r"$\bf{6\ Hour\ Temperatures\ [°F]}$" | " + name +"", loc='left', fontsize=13)
plt.title(r"$\bf{Run:}$"+ run +"", loc='right', fontsize=13)
plt.grid(True, linestyle='--', zorder=0)

#plt.subplot(2, 1, 2)
plt.subplot(gs[1])
heatmap = sns.heatmap(hmap_data, cbar=True, vmin=-50 ,vmax=120, cmap=cmap, annot=True, cbar_kws = dict(orientation='horizontal', pad=0.01, aspect=175, ticks=[-50, -40, -30, -20, -10, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120]), annot_kws = {'size':12, 'ha':'center'}, linewidth=1.5, linecolor='black')
heatmap.set_xlabel("",fontsize=12, fontweight='semibold')
heatmap.set_ylabel("",fontsize=10, fontweight='bold')
heatmap.xaxis.set_ticks_position('top')
heatmap.set(xticklabels=[])
#plt.xticks(rotation=0, ha='center', fontsize=12)
heatmap.tick_params(axis='x', length=10)
plt.yticks(rotation=0, ha='right', fontsize=12)

1 Ответ

0 голосов
/ 11 февраля 2020

Не совсем тот ответ, который вы получили, но мне кажется, что информация в столбцах и тепловая карта являются избыточными.

Разве вы не получили бы точно такую ​​же информацию, если бы раскрасили столбцы, используя цветовая карта вместо показа тепловой карты ниже.

cmap = 'coolwarm'
N=32
vmin = -50
vmax = 120
norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
sm = matplotlib.cm.ScalarMappable(cmap=cmap, norm=norm)
temps = np.random.randint(vmin,vmax,size=(N,))
labels = ['Lbl\n{:d}'.format(i+1) for i in range(N)]

min_high = np.min(temps)
max_high = np.max(temps)
max_highhght = max_high + 5
min_highhght = min_high - 5
highheight = temps - min_highhght

fig, ax1 = plt.subplots(figsize=(14,8))

#bar plot
rectstop = ax1.bar(labels, height=highheight, width=0.60, bottom=min_highhght, 
                   color=plt.get_cmap(cmap)(norm(temps)), edgecolor='black', linewidth=2)
for x,temp in enumerate(temps):
    ax1.annotate('{:.0f}'.format(temp), xy=(x, temp), xytext=(0, 2), xycoords='data', textcoords="offset points", 
                 ha='center', va='bottom', fontsize=12, fontweight='semibold')

fig.colorbar(sm, ax=ax1, pad=0.02, aspect=100, ticks=np.arange(vmin,vmax+1,10))

enter image description here

...