首页 > 解决方案 > 在热图顶部的辅助 y 轴上创建线图 在错误的 x 轴上绘制线

问题描述

我有两张表,一张是我从热图生成的,一张是为了在辅助 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轴上根本没有垂直行?并适合热图,因此这些值不会“超过”热图?

标签: pythonmatplotlibseabornheatmapline-plot

解决方案


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

为避免双斧上的白线,请将其网格关闭。

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

由于有 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()

示例图


推荐阅读