【问题标题】:pandas: plot hourly ticks with datetime.time indexpandas:使用 datetime.time 索引绘制每小时刻度
【发布时间】:2020-09-06 18:29:50
【问题描述】:

我有一个熊猫DataFrame 由一个DatetimeIndex 索引,它包含一个时间序列,即作为时间函数的一些数据。现在我想绘制一天中的行为,无论日期如何(参见this question):

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

idx = pd.date_range('2017-01-01 05:03', '2017-01-05 18:03', freq = '30min')
df = pd.Series(np.random.randn(len(idx)),  index = idx)

hours = mdates.HourLocator(interval = 1)
h_fmt = mdates.DateFormatter('%H:%M:%S')

for date, group in df.groupby(by = df.index.date):
  group.index = group.index.timetz
  group.name  = date # for legend
  ax = group.plot()
plt.ion()
plt.show()

这可行,但 x 轴上的标签有特殊的间距:

我更喜欢,例如,每小时都有刻度。基于这个SO answer,我找到了一个可行的解决方案,设置x_compat并使用HourLocator

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

idx = pd.date_range('2017-01-01 05:03', '2017-01-01 18:03', freq = '30min')
df = pd.Series(np.random.randn(len(idx)),  index = idx)

hours = mdates.HourLocator(interval = 1)
h_fmt = mdates.DateFormatter('%H:%M:%S')

with pd.plotting.plot_params.use('x_compat', True): 
  ax = df.plot() 
  ax.xaxis.set_major_locator(hours)
  ax.xaxis.set_major_formatter(h_fmt)

plt.ion()
plt.show()

这给出了以下情节(注意我已将date_range 减少到一天):

使用groupby 分割并绘制更多数据时仍然有效:

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

idx = pd.date_range('2017-01-01 05:03', '2017-01-05 18:03', freq = '30min')
df = pd.Series(np.random.randn(len(idx)),  index = idx)

hours = mdates.HourLocator(interval = 1)
h_fmt = mdates.DateFormatter('%H:%M:%S')

with pd.plotting.plot_params.use('x_compat', True): 
  for date, group in df.groupby(by = df.index.date):
    ax = group.plot()
    ax.xaxis.set_major_locator(hours)
    ax.xaxis.set_major_formatter(h_fmt)

plt.ion()
plt.show()

当然,我仍然需要在这里环绕(删除)日期。但是一旦我这样做了,我的解决方案就不再有效:

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

idx = pd.date_range('2017-01-01 05:03', '2017-01-05 18:03', freq = '30min')
df = pd.Series(np.random.randn(len(idx)),  index = idx)

hours = mdates.HourLocator(interval = 1)
h_fmt = mdates.DateFormatter('%H:%M:%S')

with pd.plotting.plot_params.use('x_compat', True): 
  for date, group in df.groupby(by = df.index.date):
    group.index = group.index.timetz
    group.name  = date # for legend
    ax = group.plot()
    ax.xaxis.set_major_locator(hours)
    ax.xaxis.set_major_formatter(h_fmt)

plt.ion()
plt.show()

计算一段时间后,这会抛出一个错误,可能是它试图从 pandas 0 开始为时间戳做记号?

RuntimeError: Locator attempting to generate 2030401 ticks from 180.0 to 84780.0: exceeds Locator.MAXTICKS

【问题讨论】:

  • 我遇到了与子图和共享 x 轴有关的相同问题。它根本不直观,我相信这是 matplotlib 错误。

标签: python pandas plot time-series


【解决方案1】:

我们可以使用ax.axis 返回 x 轴和 y 轴范围。这表明 x 轴范围很可能在内部表示为秒:

In [11]: ax.axis()
Out[11]: (180.0, 84780.0, -3.96605612012256, 3.4854575601641957)

所以我们可以使用MultipleLocator:

import matplotlib.ticker as ticker
...
n = 2
ax.xaxis.set_major_locator(ticker.MultipleLocator(3600*n))

n 小时有一次滴答声:

【讨论】:

    猜你喜欢
    • 2014-08-06
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多