【问题标题】:How do I use matplotlib.ConciseDateConverter with a Seaborn heatmap?如何将 matplotlib.ConciseDateConverter 与 Seaborn 热图一起使用?
【发布时间】:2020-09-01 18:37:49
【问题描述】:

为清楚起见进行编辑:我想避免使用 strftime 将日期时间转换为字符串。我希望轴能够像 ConcisedDateConverter 一样智能地缩放,并且我希望保留年份来区分下面的日期,如示例中所示。例如我可能有 5 年的数据,有重复的日期,但只需要在每年的 1 月 1 日显示年份,以免混淆轴。

我正在尝试使用 matplolib ConciseDateFormatter() 格式化我的 seaborn 热图日期轴,但它似乎不起作用。按照the matplotlib documentation 中的指南,我已经尝试将其添加到注册表中:

converter = mdates.ConciseDateConverter()
munits.registry[np.datetime64] = converter
munits.registry[datetime.date] = converter
munits.registry[datetime.datetime] = converter

在代码本身中为:

    locator = mdates.AutoDateLocator(minticks=3, maxticks=7)
    formatter = mdates.ConciseDateFormatter(locator)
    ax.xaxis.set_major_locator(locator)
    ax.xaxis.set_major_formatter(formatter)

但是,当我运行热图函数时,绘图 x 轴标签似乎没有变化。我的代码如下:

d1 = datetime.date(day=10, month= 5, year = 2020)
d2 = datetime.date(day=15, month= 6, year = 2020)
d3 = datetime.date(day=20, month= 7, year = 2020)
d4 = datetime.date(day=10, month= 5, year = 2021)
d5 = datetime.date(day=15, month= 6, year = 2021)
d6 = datetime.date(day=20, month= 7, year = 2022)
dates = [d1,d2,d3,d4,d5,d6]

s1 = 100
s2 = 150
s3 = 200

strikes = [s1,s2,s3]

chain = []
for d in dates:
  for s in strikes:
    val = random.randint(-100,100)
    o = [d,s,val]
    chain.append(o)

df = pd.DataFrame(chain, columns = ['Date','Strike','Value'])
df1 = df.pivot("Strike", "Date", "Value")

pal = sb.diverging_palette(0, 500, sep=1, n=5)

fig, ax = plt.subplots(figsize=(16,9))

# locator = mdates.AutoDateLocator()
# formatter = mdates.ConciseDateFormatter(locator)
# ax.xaxis.set_major_locator(locator)
# ax.xaxis.set_major_formatter(formatter)

sb.heatmap(df1, annot=True, fmt="d", center=0,cmap=pal, ax=ax)

plt.show()

输出如下:

Output Heatmap

我想要如下输出,每列下方有月份和日期以及需要澄清的年份:

Desired Heatmap

有什么方法可以根据需要(或类似)格式化 seaborn x 轴。我想避免制作单独的 x 轴列表,然后运行 ​​date.strftime 并对字符串进行硬编码。最好像上面文档中的示例那样半智能地缩放日期。

要注意的一个有趣的点是,如果我把

ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)

热图函数之后的行,该过程失败并出现值错误,声称并非所有 x 值都是日期时间。我尝试了将datetime.date 对象转换为datetime.datetime 的明显解决方案,但仍然出现相同的错误。

ValueError: view limit minimum 0.0 is less than 1 and is an invalid Matplotlib date value. This often happens if you pass a non-datetime value to an axis that has datetime units

【问题讨论】:

  • 您好,欢迎来到 Stackoverflow。如果您更简洁地解释您的问题,这将非常有帮助。据我所知,您要做的是从日期中删除年份。我建议使用 strtime pandas.pydata.org/pandas-docs/stable/reference/api/…
  • 嗨!感谢您的回答,但是我明确表示我想避免使用 strftime 将日期时间转换为字符串。我希望轴能够像 ConcisedDateConverter 一样智能地缩放,并且我希望保留年份来区分下面的日期,如示例中所示。例如我可能有 5 年的数据,有重复的日期,但只需要在每年的 1 月 1 日显示年份,以免混淆轴。
  • 在这种情况下,您可能想要使用 matplotlib setticklabels matplotlib.org/3.1.1/api/_as_gen/… 之类的东西,或者对于更复杂的操作,例如 set_major_formatter matplotlib.org/api/_as_gen/…
  • 我正在使用 set_major_formatter(如我的代码所示),但这似乎没有传递给 seaborn 热图

标签: python pandas matplotlib seaborn heatmap


【解决方案1】:

事实证明,Seaborn 热图函数在对应于 x 值总数的范围内绘制一个整数,因此它不保留日期时间信息。因此不可能将 set_major_formatter 与 seaborn 直方图一起使用。我将尝试使用imshow 做同样的事情

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-18
    • 2021-06-12
    • 2020-04-10
    • 1970-01-01
    • 2019-10-21
    • 2021-04-24
    • 1970-01-01
    相关资源
    最近更新 更多