9

使用 pandas 的内置绘图功能绘制时间序列时,它似乎忽略了我的索引的时区:它始终使用 UTC 时间作为 x 轴。一个例子:

import numpy as np
import matplotlib.pyplot as plt
from pandas import rolling_mean, DataFrame, date_range

rng = date_range('1/1/2011', periods=200, freq='S', tz="UTC")
data = DataFrame(np.random.randn(len(rng), 3), index=rng, columns=['A', 'B', 'C'])
data_cet = data.tz_convert("CET")

# plot with data in UTC timezone
fig, ax = plt.subplots()
data[["A", "B"]].plot(ax=ax, grid=True)
plt.show()

# plot with data in CET timezone, but the x-axis remains the same as above
fig, ax = plt.subplots()
data_cet[["A", "B"]].plot(ax=ax, grid=True)
plt.show()

情节没有改变,尽管索引有:

In [11]: data.index[0]
Out[11]: <Timestamp: 2011-01-01 00:00:00+0000 UTC, tz=UTC>
In [12]: data_cet.index[0]
Out[12]: <Timestamp: 2011-01-01 01:00:00+0100 CET, tz=CET>

我应该提交一个错误,还是我错过了什么?

4

3 回答 3

7

这绝对是一个错误。我在github上创建了一份报告。原因是在内部,pandas 将常规频率 DatetimeIndex 转换为 PeriodIndex 以挂钩到 pandas 中的格式化程序/定位器,而目前 PeriodIndex 不保留时区信息。请继续关注修复。

于 2012-10-23T15:58:16.873 回答
1
from pytz import timezone as ptz
import matplotlib as mpl
...
data.index = pd.to_datetime(data.index, utc=True).tz_localize(tz=ptz('<your timezone>'))
...
mpl.rcParams['timezone'] = data.index.tz.zone

...之后 matplotlib 打印为该区域而不是 UTC。

然而!请注意,如果您需要注释,注释的 x 位置仍需要使用 UTC,即使传递给 data.loc[] 或 data.at[] 的字符串将被假定在设置的时区中!

例如,我需要显示一系列标有时间戳的垂直线:(这是在大多数情节调用之后,并注意 sels 中的时间戳字符串是 UTC)

sels = ['2019-03-21 3:56:28',
         '2019-03-21 4:00:30',
         '2019-03-21 4:05:55',
         '2019-03-21 4:13:40']
ax.vlines(sels,125,145,lw=1,color='grey') # 125 was bottom, 145 was top in data units
for s in sels:
    tstr = pd.to_datetime(s, utc=True)\
    .astimezone(tz=ptz(data.index.tz.zone))\
    .isoformat().split('T')[1].split('+')[0]
    ax.annotate(tstr,xy=(s,125),xycoords='data',
              xytext=(0,5), textcoords='offset points', rotation=90,
              horizontalalignment='right', verticalalignment='bottom')

这会将灰色垂直线放在手动选择的时间sels,并以当地时区的小时、分钟和秒标记它们。(企业从字符串中.split()[]丢弃日期和时区信息)。.isoformat()

但是当我需要使用相同s的 in实际从数据中获取相应的值时sels,我不得不使用有点尴尬的:

data.tz_convert('UTC').at[s]

而只是

data.at[s]

失败,KeyError因为 pandas 解释s是在data.index.tz时区中,所以解释,时间戳超出了内容的范围data

于 2019-04-02T04:43:15.747 回答
0

如何处理 UTC 到本地时间的转换

import time
import matplotlib.dates
…
tz = pytz.timezone(time.tzname[0])
…
ax.xaxis.set_major_locator(matplotlib.dates.HourLocator(interval=1, tz=tz))
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%H', tz=tz))
于 2017-10-27T12:01:51.823 回答