如何在 Seaborn 热图上编辑日期时间格式而不更改日期?

Nih*_*lum 3 python datetime dataframe seaborn

我正在处理卫星数据,我用这些数据提取了几十年来点的速度。我有一个带有日期时间索引的数据框,以及列中的速度(每列代表 1 点)。该数据库非常不完整,并且这些点不一定与其他点同时具有值​​。

我用seaborn绘制了一个热图,它可以工作,但是日期时间显示太多信息(我只想要“YYYY-MM-DD”。但是,当我计算该行时,ax.yaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d') )日期不再正确。我该如何解决这个问题?(第二张图显示了当 DateFormatter 行被注释掉时它是如何正确显示的)。

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

v1 = np.array([1671., 1756.,   1704., 1574., 1589.,   1772.,   1652., 1778., 1719.,
             1699.], dtype=float)
    
dv1 = np.array(['2015-01-21T00:00:00.032000000', '2015-01-29T00:00:00.016000000',
           '2014-06-11T00:00:00.544000000', '2014-12-20T00:00:00.160000000',
           '2014-12-28T00:00:00.144000000', '2015-01-05T00:00:00.192000000',
           '2014-07-29T00:00:00.512000000', '2015-03-02T00:00:00.080000256',
           '2015-07-08T00:00:00.112000000', '2015-08-25T00:00:00.272000000'],
          dtype='datetime64[ns]')
    
v2 = np.array([1647., 1758., 1722.], dtype=float)
    
dv2 = np.array(['2015-08-10T00:00:00.032000000', '2015-02-18T00:00:00.016000000',
           '2014-09-19T00:00:00.544000000'],
          dtype='datetime64[ns]')

df1 = pd.DataFrame({'Velocity0': v1}, index=pd.to_datetime(dv1))

df2 = pd.DataFrame({'Velocity1': v2}, index=pd.to_datetime(dv2))

df1 = df1.append(df2)

df1 = df1.sort_index()

df1 = df1.sort_index()

plt.figure(figsize=(15,15))
ax = sns.heatmap(df1)
for item in ax.get_yticklabels():
    item.set_rotation(0)

for item in ax.get_xticklabels():
    item.set_rotation(90)
    
ax.yaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d') )

plt.figure(figsize=(15,15))
plt.rcParams.update({'font.size': 20})
plt.plot(df1)
Run Code Online (Sandbox Code Playgroud)

日期错误的 Seaborn 情节 具有正确日期但格式错误的相同绘图

Pat*_*ald 5

为了使 mdatesDateFormatter工作,您需要在 y 轴上有一个基于matplotlib dateunits 的连续时间刻度。问题在于seaborn 热图的x 轴和y 轴使用整数范围。您可以通过打印刻度位置来检查 y 轴单位:

print(ax.get_yticks())
# [ 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]
Run Code Online (Sandbox Code Playgroud)

这就是为什么DateFormatter没有效果的原因。strftime相反,您可以使用以下方法来格式化标签DatetimeIndex

import numpy as np     # v 1.19.2
import pandas as pd    # v 1.1.3
import seaborn as sns  # v 0.11.0

v1 = np.array([1671., 1756., 1704., 1574., 1589., 1772., 1652., 1778., 1719., 1699.])
dv1 = np.array(['2015-01-21T00:00:00.032000000', '2015-01-29T00:00:00.016000000',
                '2014-06-11T00:00:00.544000000', '2014-12-20T00:00:00.160000000',
                '2014-12-28T00:00:00.144000000', '2015-01-05T00:00:00.192000000',
                '2014-07-29T00:00:00.512000000', '2015-03-02T00:00:00.080000256',
                '2015-07-08T00:00:00.112000000', '2015-08-25T00:00:00.272000000'],
               dtype='datetime64[ns]')
    
v2 = np.array([1647., 1758., 1722.], dtype=float)
dv2 = np.array(['2015-08-10T00:00:00.032000000', '2015-02-18T00:00:00.016000000',
                '2014-09-19T00:00:00.544000000'],
               dtype='datetime64[ns]')

df1 = pd.DataFrame({'Velocity0': v1}, index=dv1)
df2 = pd.DataFrame({'Velocity1': v2}, index=dv2)
df1 = df1.append(df2).sort_index()

ax = sns.heatmap(df1)
ax.figure.set_size_inches(6,6)
ticklabels = [df1.index[int(tick)].strftime('%Y-%m-%d') for tick in ax.get_yticks()]
ax.set_yticklabels(ticklabels);
Run Code Online (Sandbox Code Playgroud)

热图