【问题标题】:Plot datetime series as categorical data in matplotlib在 matplotlib 中将日期时间序列绘制为分类数据
【发布时间】:2021-09-01 14:02:59
【问题描述】:

TLDR:我正在寻找一种将时间戳列表绘制为等距数据点的方法,mpl 决定显示哪些标签。

如果只有通过将时间戳转换为字符串(并将它们绘制为分类轴)才能等距绘制带时间戳的数据点,我的问题也可以表述为:如何让mpl 自动删除标签来自过度拥挤的分类轴?


详情:

我有一个包含每月数据的时间序列,我想将其绘制为条形图。我的问题是matplotlib.pyplot 自动在时间轴上绘制这些数据:

import matplotlib.pyplot as plt
import pandas as pd
fig, ax = plt.subplots(1, 1, )
s = pd.Series(range(3,7), pd.date_range('2021', freq='MS', periods=4))
ax.bar(s.index, s.values, 27) # width 27 days
ax.set_ylabel('income [Eur]')

通常,这就是我想要的,但是对于月度数据,它看起来很奇怪,因为 2 月明显更短。 我想要的是等距绘制数据。有没有办法强制这样做

重要的是,我想保留这样的行为,例如一旦 x 轴变得过于拥挤,只绘制第二个或第三个标签,而无需手动调整。

我尝试过或不想做的事情:

  • 我可以通过调整条的宽度来使条之间的间隙相同。但是,我正在绘制收入数据 [Eur],这意味着不均匀的条形宽度具有误导性。

  • 我可以将时间戳转换为字符串,以便分类绘制数据:

s = pd.Series(range(3,7), pd.date_range('2021', freq='MS', periods=4))
x = [f'{ts.year}-{ts.month:02}' for ts in s.index]
ax.bar(x, s.values, 0.9) # width now as fraction of spacing between datapoints

但是,这导致mpl 认为必须绘制每个标签,这会变得拥挤:

s = pd.Series(range(3,17), pd.date_range('2021', freq='MS', periods=14))
x = [f'{ts.year}-{ts.month:02}' for ts in s.index]
ax.bar(x, s.values, 0.9) # width now as fraction of spacing between datapoints

【问题讨论】:

  • 您是否正在寻找将数据类型从自定义类型转换为类别类型?
  • 感谢您的评论。不;如果我这样做,将始终显示每个标签。如果可能的话,我想将它们转换为由自定义标签表示的数值。因此,就像任何其他数值轴一样,使用适合可用空间的标签间距。

标签: python matplotlib plot


【解决方案1】:

您可以使用MaxNLocator 分隔您的分类标记。

  • 给定带有分类标签的更大系列样本:

    s = pd.Series(range(3,17), pd.date_range('2021', freq='MS', periods=14))
    x = [f'{ts.year}-{ts.month:02}' for ts in s.index]
    
    fig, ax = plt.subplots()
    ax.bar(x, s.values, 0.9)
    ax.set_ylabel('income [Eur]')
    
  • MaxNLocator 与指定数量的箱(或'auto')一起应用:

    from matplotlib.ticker import MaxNLocator
    
    locator = MaxNLocator(nbins=5) # or nbins='auto'
    ax.xaxis.set_major_locator(locator)
    

【讨论】:

  • 感谢@tdy 的回答,但是,此解决方案仍使用日期时间轴。月份是根据它们的持续时间间隔的,尤其是在 2 月和 3 月之间。 - 我正在寻找一种解决方案,它可以均匀地绘制月份(正如我通过定义 x 实现的那样),但如果标签太多(与“正常”分类轴不同)缺失值,它也会丢弃标签可以推导出来。
  • 我已经更新了这个问题,让它更清楚我正在寻找的究竟是什么。
  • @ElRudi 啊,明白了,那么我相信您正在寻找MaxNLocator(答案已更新)
猜你喜欢
  • 2021-12-29
  • 1970-01-01
  • 2019-05-14
  • 1970-01-01
  • 2014-03-24
  • 2019-12-11
  • 1970-01-01
  • 1970-01-01
  • 2021-09-25
相关资源
最近更新 更多