如何在Matplotlib中使用时区处理时间? [英] How to handle times with a time zone in Matplotlib?
问题描述
我有一些数据点,它们的横坐标是带有时区的datetime.datetime
对象(它们的tzinfo
恰好是通过MongoDB获得的bson.tz_util.FixedOffset
).
I have data points whose abscissas are datetime.datetime
objects with a time zone (their tzinfo
happens to be a bson.tz_util.FixedOffset
obtained through MongoDB).
当我用scatter()
绘制它们时,刻度标签的时区是什么?
When I plot them with scatter()
, what is the time zone of the tick labels?
在matplotlibrc
中更改timezone
不会更改显示的绘图中的任何内容(我必须误解了关于时区的讨论.
Changing the timezone
in matplotlibrc
does not change anything in the displayed plot (I must have misunderstood the discussion on time zones in the Matplotlib documentation).
我对plot()
(而不是scatter()
)做了一些实验.给定单个日期时,它将对其进行绘制并忽略时区.但是,给定多个日期时,它使用固定的时区,但是如何确定呢?我在文档中找不到任何内容.
I experimented a little with plot()
(instead of scatter()
). When given a single date, it plots it and ignores the time zone. However, when given multiple dates, it uses a fixed time zone, but how is it determined? I can't find anything in the documentation.
最后,plot_date()
应该是这些时区问题的 解决方案吗?
Finally, is plot_date()
supposed to be the solution to these time zone problems?
推荐答案
问题已经在注释中得到了回答.但是我自己仍然在为时区挣扎.为了清楚起见,我尝试了所有组合.我认为您有两种主要方法,具体取决于您的datetime对象是否已在所需的时区中或在其他时区中,我尝试在下面对其进行描述.可能我仍然错过/混合了一些东西.
The question was already answered in the comments sort of. However I was still struggling with timezones myself. To get it clear I tried all combinations. I think you have two main approaches depending on if your datetime objects are already in the desired timezone or are in a different timezone, I tried to describe them below. It's possible that I still missed/mixed something..
时间戳记(日期时间对象): UTC时间 所需的显示:在特定时区
Timestamps (datetime objects): in UTC Desired display: in specific timezone
- 设置 xaxis_date() 设置为您想要的显示时区(默认为
rcParam['timezone']
,对于我来说是UTC)
- Set the xaxis_date() to your desired display timezone (defaults to
rcParam['timezone']
which was UTC for me)
时间戳记(日期时间对象):在特定时区 所需的显示:在其他特定时区
Timestamps (datetime objects): in a specific timezone Desired display: in a different specific timezone
- Feed your plot function datetime objects with the corresponding timezone (
tzinfo=
) - Set the rcParams['timezone'] to your desired display timezone
- Use a dateformatter (even if you are satisfied with the format, the formatter is timezone aware)
如果您使用plot_date(),还可以传入tz关键字,但是对于散点图则无法实现.
If you are using plot_date() you can also pass in the tz keyword but for a scatter plot this is not possible.
当您的源数据包含unix时间戳时,如果要使用matplotlib时区功能,请确保从datetime.datetime.utcfromtimestamp()
中明智地选择,而不要使用utc:fromtimestamp()
.
When your source data contains unix timestamps, be sure to choose wisely from datetime.datetime.utcfromtimestamp()
and without utc: fromtimestamp()
if you are going to use matplotlib timezone capabilities.
这是我做过的实验(在这种情况下,是在scatter()上),可能很难遵循,但是只是在这里写给任何愿意的人.请注意,第一个点在时间出现(每个子图的x轴不在同一时间开始):
This is the experimenting I did (on scatter() in this this case), it's a bit hard to follow maybe, but just written here for anyone who would care. Notice at what time the first dots appear (the x axis does not start on the same time for each subplot):
源代码:
import time,datetime,matplotlib
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
from dateutil import tz
#y
data = np.array([i for i in range(24)])
#create a datetime object from the unix timestamp 0 (epoch=0:00 1 jan 1970 UTC)
start = datetime.datetime.fromtimestamp(0)
# it will be the local datetime (depending on your system timezone)
# corresponding to the epoch
# and it will not have a timezone defined (standard python behaviour)
# if your data comes as unix timestamps and you are going to work with
# matploblib timezone conversions, you better use this function:
start = datetime.datetime.utcfromtimestamp(0)
timestamps = np.array([start + datetime.timedelta(hours=i) for i in range(24)])
# now add a timezone to those timestamps, US/Pacific UTC -8, be aware this
# will not create the same set of times, they do not coincide
timestamps_tz = np.array([
start.replace(tzinfo=tz.gettz('US/Pacific')) + datetime.timedelta(hours=i)
for i in range(24)])
fig = plt.figure(figsize=(10.0, 15.0))
#now plot all variations
plt.subplot(711)
plt.scatter(timestamps, data)
plt.gca().set_xlim([datetime.datetime(1970,1,1), datetime.datetime(1970,1,2,12)])
plt.gca().set_title("1 - tzinfo NO, xaxis_date = NO, formatter=NO")
plt.subplot(712)
plt.scatter(timestamps_tz, data)
plt.gca().set_xlim([datetime.datetime(1970,1,1), datetime.datetime(1970,1,2,12)])
plt.gca().set_title("2 - tzinfo YES, xaxis_date = NO, formatter=NO")
plt.subplot(713)
plt.scatter(timestamps, data)
plt.gca().set_xlim([datetime.datetime(1970,1,1), datetime.datetime(1970,1,2,12)])
plt.gca().xaxis_date('US/Pacific')
plt.gca().set_title("3 - tzinfo NO, xaxis_date = YES, formatter=NO")
plt.subplot(714)
plt.scatter(timestamps, data)
plt.gca().set_xlim([datetime.datetime(1970,1,1), datetime.datetime(1970,1,2,12)])
plt.gca().xaxis_date('US/Pacific')
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%H:%M(%d)'))
plt.gca().set_title("4 - tzinfo NO, xaxis_date = YES, formatter=YES")
plt.subplot(715)
plt.scatter(timestamps_tz, data)
plt.gca().set_xlim([datetime.datetime(1970,1,1), datetime.datetime(1970,1,2,12)])
plt.gca().xaxis_date('US/Pacific')
plt.gca().set_title("5 - tzinfo YES, xaxis_date = YES, formatter=NO")
plt.subplot(716)
plt.scatter(timestamps_tz, data)
plt.gca().set_xlim([datetime.datetime(1970,1,1), datetime.datetime(1970,1,2,12)])
plt.gca().set_title("6 - tzinfo YES, xaxis_date = NO, formatter=YES")
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%H:%M(%d)'))
plt.subplot(717)
plt.scatter(timestamps_tz, data)
plt.gca().set_xlim([datetime.datetime(1970,1,1), datetime.datetime(1970,1,2,12)])
plt.gca().xaxis_date('US/Pacific')
plt.gca().set_title("7 - tzinfo YES, xaxis_date = YES, formatter=YES")
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%H:%M(%d)'))
fig.tight_layout(pad=4)
plt.subplots_adjust(top=0.90)
plt.suptitle(
'Matplotlib {} with rcParams["timezone"] = {}, system timezone {}"
.format(matplotlib.__version__,matplotlib.rcParams["timezone"],time.tzname))
plt.show()
这篇关于如何在Matplotlib中使用时区处理时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!