如何在Matplotlib中使用时区处理时间? [英] How to handle times with a time zone in Matplotlib?

查看:108
本文介绍了如何在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

  • 使用对应的时区(tzinfo=)
  • 馈送绘图函数日期时间对象
  • 将rcParams ['timezone']设置为所需的显示时区
  • 使用dateformatter(即使您对格式满意,
  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆