简体   繁体   English

在热图顶部的辅助 y 轴上创建线 plot 在错误的 x 轴上绘制线

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

I have two tables, one which I generate from heatmap and one which Ineed in order to draw line chart on secondary y axis.我有两张表,一张是我从热图生成的,一张是为了在辅助 y 轴上绘制折线图而需要的。 Creating the heatmap works no problem:创建热图没有问题:

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)
    

在此处输入图像描述

The problem starts when I try to plot line on top of the heatmap.当我尝试在热图顶部使用 plot 线时,问题就开始了。 The line should have the same x-axis values and the values should be in secondary y-axis.该线应具有相同的 x 轴值,并且这些值应位于辅助 y 轴中。 This is how the line df looks like:这是 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
...

I have tried to plot it on top as explained here :我已经尝试将plot放在上面,如下所述:

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

but then I get the line "shifted" to the left side, I get new "rows" on the y axis (the grey ones) and is just wrong.但是后来我把线“移”到了左边,我在 y 轴(灰色的)上得到了新的“行”,这是错误的。 在此处输入图像描述

How can I align the line to match to the x-axis?如何对齐线以匹配 x 轴? and also to the y-axis not to have vertical rows at all?并且在y轴上根本没有垂直行? and to fit the heatmap so the values are not "oveR" the heat map?并适合热图,因此这些值不会“超过”热量 map?

Internally, the ticks of the heatmap are categorical.在内部,热图的刻度是分类的。 Moreover, they are shifted by a half.此外,它们移动了一半。 This makes tick 14 internally having position 0.5, 15 at 1.5 etc. You can correct the lineplot by subtracting the first day and adding 0.5.这使得刻度14在内部具有 position 15在 1.5 等。您可以通过减去第一天并添加 0.5 来校正线图。

To avoid the white lines from the twin ax, set its grid off.为避免双斧上的白线,请将其网格关闭。

To avoid the grey bars at the top and bottom, use plt.subplots_adjust() with the y-dimensions of the first ax .要避免顶部和底部的灰色条,请使用plt.subplots_adjust()和第一个ax的 y 维度。

As there are 7 rows of cells, a trick to align the ticks of the twin ax with the borders between the cells, could be to set its y limits 7*50 separated.由于有 7 行单元格,将双轴的刻度与单元格之间的边界对齐的技巧可能是将其 y 限制设置为 7*50 分隔。 For example ax2.set_ylim(150, 500) .例如ax2.set_ylim(150, 500)

Here is some example code:这是一些示例代码:

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

示例图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM