【问题标题】:I have daily data. How can I restrict the ticks to just the months?我有每日数据。我怎样才能将蜱虫限制在几个月内?
【发布时间】:2019-12-12 02:09:42
【问题描述】:

我有一个数据框,其中一列包含一年的每日日期和两列数据。我正在创建数据的热图,使用日期作为 y 轴。如何将 y 轴刻度限制为仅几个月?我同意“一月”出现在代表本月 1 日的行或代表月中的行。出于可扩展性的目的,“日期”列将始终按时间顺序排列,并且始终具有恒定增量,但不一定像我的示例中那样恰好是 1 天。

df = pd.DataFrame({'Date':[dt.date(2019,1,1) + dt.timedelta(days=x) for x in range(365)],
               'a':[x%5 for x in range(365)], 'b':[x%3 for x in range(365)]})
print(df.head())
         Date  a  b
0  2019-01-01  0  0
1  2019-01-02  1  1
2  2019-01-03  2  2
3  2019-01-04  3  0
4  2019-01-05  4  1

1) 标准热图代码。这会导致 y 轴混乱。

ax = sns.heatmap(data=df[['a','b']], yticklabels=df['Date'])

2) 使用 matplotlib.dates 中的 MonthLocator(作为 'mdates')。我无法让它工作。这会导致没有 y 轴标签。

ax = sns.heatmap(data=df[['a','b']], yticklabels=df['Date'])
ax.yaxis.set_major_locator(mdates.MonthLocator())

3) 使用花哨的数学。这不能说明天数不相等的月份。

ax = sns.heatmap(data=df[['a','b']])
ax.set_yticks(range(0,df.shape[0]-1,df.shape[0]//12)) #13 evenly spaced tick marks
ax.set_yticklabels(df['Date'].apply(lambda x: x.strftime('%B %d %Y')).iloc[range(0,df.shape[0]-1,df.shape[0]//12)]) #Select dates matching tick marks

4) 这里没有示例代码。我尝试找到“日”为 1 的日期。这不是问题。我只是不知道如何创建适当的不均匀间隔的刻度来分配它们。

【问题讨论】:

    标签: python datetime seaborn heatmap


    【解决方案1】:

    我想这里唯一干净的解决方案是使用 matplotlib 并格式化轴。为此,将日期转换为数字,并将图像的范围设置为日期值的范围。 (准确地说,也可以加上半天,这样一天就在每个像素的中间)。这假设日期(以及像素)是等距的。

    import numpy as np
    import pandas as pd
    import datetime as dt
    import matplotlib.pyplot as plt
    import matplotlib.dates as mdates
    
    df = pd.DataFrame({'Date':[dt.date(2019,1,1) + dt.timedelta(days=x) for x in range(365)],
                   'a':[x%5 for x in range(365)], 'b':[x%3 for x in range(365)]})
    
    
    x = np.arange(len(df.columns[1:]))
    y = mdates.date2num(df['Date'].values)
    z = df[["a", "b"]].values
    
    dy = y[1]-y[0]
    extent = [-0.5, len(x)-0.5, y[0]-dy, y[-1]+dy]
    
    fig, ax = plt.subplots()
    im = ax.imshow(z, aspect="auto", extent=extent)
    ax.yaxis_date()
    ax.invert_yaxis()
    ax.set(xticks=x, xticklabels=df.columns[1:])
    fig.colorbar(im)
    
    plt.show()
    

    现在您也可以毫无问题地使用 matplotlib 日期定位器和格式化程序

    【讨论】:

    • 据我了解,这基本上是使用我的 seaborn 热图并使用 matplotlib 的 imshow 获得相对相同的输出,为我的第四种方法做好准备。我试了一下(感谢复制和粘贴代码)并添加了定位器和格式化程序行,它看起来不错。这有点有趣,因为最初我使用的是 imshow,但切换到热图是因为我不喜欢使用嵌套的 for 循环从 (r,c) 数据帧创建我的 (r,c,n) 数组(实际上是我之前的 stackoverflow 问题)。
    猜你喜欢
    • 2023-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 2010-10-16
    • 2022-08-02
    • 1970-01-01
    相关资源
    最近更新 更多