简体   繁体   English

pandas: plot 每小时刻度与 datetime.time 索引

[英]pandas: plot hourly ticks with datetime.time index

I have a pandas DataFrame indexed by a DatetimeIndex that holds a time series, ie some data as a function of time.我有一个 pandas DataFrame由包含时间序列的DatetimeIndex索引,即一些数据作为时间的 function 。 Now I would like to plot the behavior over the day regardless of the date (cf. this question ):现在我想 plot 不管日期如何(参见这个问题):

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()

This works but the labels on the x-axis have peculiar spacings:这可行,但 x 轴上的标签有特殊的间距: 情节1

I'd prefer, eg, to have ticks every hour on the hour.例如,我更喜欢每小时每小时都有一次滴答声。 Based on this SO answer I found a solution that works, setting x_compat and using the HourLocator :基于这个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()

This gives the following plot (note I have reduced the date_range to one day here):这给出了以下 plot (注意我在这里将date_range减少到一天): 情节2

It still works when splitting with groupby and plotting more data:在使用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()

情节3

Of course, I still need to wrap around (drop) the date here.当然,我仍然需要在这里环绕(删除)日期。 But once I do that, my solution no longer works:但是一旦我这样做了,我的解决方案就不再有效:

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()

After computing for a while, this throws an error, maybe it's trying to make ticks starting at pandas 0 for timestamps?经过一段时间的计算,这会引发一个错误,也许它试图从 pandas 0 开始为时间戳制作刻度?

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

We can use ax.axis to return the x- and y-axis ranges.我们可以使用ax.axis返回 x 轴和 y 轴范围。 This reveals that the x-axis range is likely represented as seconds internally:这表明 x 轴范围很可能在内部表示为秒:

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

So we can use the MultipleLocator :所以我们可以使用MultipleLocator

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

to have ticks every n hours:n小时有一次滴答声:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM