首页 > 解决方案 > 如何在 seaborn 热图的特定位置插入网格线

问题描述

我有以下数据和热图,希望对网格线的格式有所帮助:

import pandas as pd
import numpy as np

data = [
    ['tom', 1, 1, 1, '0:00', '10:26'],
    ['tom', 1, 1, 2, '15:30', '18:50'],
    ['tom', 1, 2, 1, '2:00', '9:15'],
    ['tom', 1, 2, 2, '13:10', '22:40'],
    ['tom', 2, 1, 1, '5:00', '22:15'],
    ['tom', 2, 2, 1, '0:00', '13:40']
]
# Create the pandas DataFrame
df = pd.DataFrame(
    columns=['Name',
             'Day',
             'AllottedPeriod',
             'AttemptNo',
             'StartTime',
             'EndTime'],
    data=data,
)


def parse_time_periods(x):
    start_minute, start_second = x['StartTime'].split(':')
    end_minute, end_second = x['EndTime'].split(':')
    # calculate the start and end time in seconds
    start = (int(start_minute) * 60) + int(start_second)
    end = (int(end_minute) * 60) + int(end_second)
    test_range = range(start, end)
    for i in range(1, 26, 1):
        # create range to check for intercection with testing time
        time_range = range((i - 1) * 60, i * 60)
        # create variables to indicate if there is overlap between
        # test time and minute range. For example, if a test was active
        # between minute 10 and minute 15, column `15` will be 1
        if len(set(test_range).intersection(time_range)) > 0:
            x[f'{i:02}'] = 1
    return x


df = df.apply(lambda x: parse_time_periods(x), axis=1).fillna(0)

stacked_df = df.drop(columns=['StartTime', 'EndTime','AttemptNo']).groupby(
    by=['Name', 'Day', 'AllottedPeriod']
).agg(sum).unstack().swaplevel(0, 1, 1).sort_index(1)

import seaborn as sns
import matplotlib.pyplot as plt
f, ax = plt.subplots(figsize=(10,3))
cmap = plt.cm.OrRd_r
ax = sns.heatmap(stacked_df,cbar=False,cmap=cmap)

plt.show()

在此处输入图像描述

如何插入:a)每条线的水平网格线 b)该点的垂直网格线2-01

只是努力找出方法。任何帮助,将不胜感激!非常感谢!

标签: pythonpandasseaborn

解决方案


“sns”无法显示网格线,所以我使用“matplotlib”创建绘制的水平和垂直线。ax.hlines(), ax.vlines().

h = ax.get_yticks()
print(h)
[0.5 1.5]
w = ax.get_xticks()
print(w)
[ 0.5  1.5  2.5  3.5  4.5  5.5  6.5  7.5  8.5  9.5 10.5 11.5 12.5 13.5
 14.5 15.5 16.5 17.5 18.5 19.5 20.5 21.5 22.5 23.5 24.5 25.5 26.5 27.5
 28.5 29.5 30.5 31.5 32.5 33.5 34.5 35.5 36.5 37.5 38.5 39.5 40.5 41.5
 42.5 43.5 44.5 45.5]

ax.hlines((h[0]+h[1])/2,w[-1],w[:0], linestyle='dashed', linewidth=2, color="gray")
ax.vlines(24.5,h[1]+0.5,h[0]-0.5, linestyle='dashed', linewidth=2, color="gray")

在此处输入图像描述


推荐阅读