在热图顶部的次要 y 轴上创建线图在错误的 x 轴上绘制线

Create line plot on secondary y axis on top of heatmap draw line on wrong x-axis

我有两个表,一个是我从热图生成的,另一个是我需要的,以便在第二个 y 轴上绘制折线图。 创建热图没问题:

green = sns.light_palette("seagreen", reverse=True, as_cmap=True)
green.set_over('tomato')
sns.set(rc={'figure.figsize': (20.7, 10.27)})
sns.set(font_scale=2)
ax=sns.heatmap(df, square=True, linewidths=.5, annot=False, fmt='.3f',
               cmap=green, vmin=0, vmax=0.05)
    

当我尝试在热图顶部绘制线条时出现问题。该线应具有相同的 x 轴值,并且这些值应位于辅助 y 轴上。这是 df 行的样子:

>>>day     value
0  14       315.7
1  15       312.3
2  16       305.9
3  17       115.2
4  18       163.2
5  19       305.78
...

我已经尝试按照说明将其绘制在顶部 :

green = sns.light_palette("seagreen", reverse=True, as_cmap=True)
green.set_over('tomato')
sns.set(rc={'figure.figsize': (20.7, 10.27)})
sns.set(font_scale=2)
ax=sns.heatmap(df, square=True, linewidths=.5, annot=False, fmt='.3f',
              cmap=green, vmin=0, vmax=0.05)

ax2=plt.twinx()
ax2.plot(df_line['day'], df_line['value'],color="blue")
line = ax2.lines[0]
line.set_xdata(line.get_xdata() + 0.5)


plt.show()

但后来我将线“移动”到左侧,我在 y 轴(灰色的)上得到新的“行”,这是错误的。

如何对齐线以匹配 x 轴?以及 y 轴根本没有垂直行?并拟合热图,使值不“超过”热图?

在内部,热图的刻度是分类的。此外,它们移动了一半。这使得 tick 14 在内部具有位置 0.5,15 在 1.5 等。您可以通过减去第一天并添加 0.5 来更正线图。

为了避免双斧出现白线,请关闭其网格。

为了避免顶部和底部的灰色条,使用 plt.subplots_adjust() 和第一个 ax 的 y 维度。

由于有 7 行单元格,将双轴的刻度与单元格之间的边界对齐的技巧可能是将其 y 限制设置为 7*50 分隔。例如 ax2.set_ylim(150, 500).

下面是一些示例代码:

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as  np
import pandas as pd

days = np.arange(14, 31)
hours = np.arange(9, 16)
df_data = pd.DataFrame({'day': np.tile(days, len(hours)),
                        'hour': np.repeat(hours, len(days)),
                        'value': np.random.uniform(0, 0.1, len(hours) * len(days))})
df = df_data.pivot('hour', 'day', 'value')
green = sns.light_palette("seagreen", reverse=True, as_cmap=True)
green.set_over('tomato')
sns.set(rc={'figure.figsize': (20.7, 10.27)})
sns.set(font_scale=2)
ax = sns.heatmap(df, square=True, linewidths=.5, annot=False, cmap=green, vmin=0, vmax=0.05, cbar=False)
ax.tick_params(axis='y', length=0, labelrotation=0, pad=10)

df_line = pd.DataFrame({'day': days, 'value': np.random.uniform(120, 400, len(days))})
ax_bbox = ax.get_position()
ax2 = ax.twinx()
ax2.plot(df_line['day'] - df_line['day'].min() + 0.5, df_line['value'], color="blue", lw=3)
ax2.set_ylim(100, 450)
ax2.grid(False)
plt.subplots_adjust(bottom=ax_bbox.y0, top=ax_bbox.y1)  # to shrink the height of ax2 similar to ax
plt.show()