python - 如何处理 Matplotlib 中带时区的时间?

标签 python matplotlib plot timezone python-datetime

我有一些数据点,其横坐标是带有时区的 datetime.datetime 对象(它们的 tzinfo 恰好是 bson.tz_util.FixedOffset 通过 MongoDB 获取)。

当我用 scatter() 绘制它们时,刻度标签的时区是多少?

更改 matplotlibrc 中的 timezone 不会更改显示图中的任何内容(我一定是误解了 Matplotlib 文档中的 discussion on time zones)。

我用 plot()(而不是 scatter())做了一些实验。当给定一个日期时,它会绘制它并忽略时区。但是,当给定多个日期时,它使用固定的时区,但它是如何确定的呢?我在文档中找不到任何内容。

最后,plot_date() 应该是这些时区问题的解决方案吗?

最佳答案

这个问题已经在评论中得到了解答。但是,我自己仍在与时区作斗争。为了弄清楚,我尝试了所有组合。我认为你有两种主要方法,具体取决于你的日期时间对象是否已经在所需的时区或不同的时区,我试图在下面描述它们。可能我仍然遗漏/混合了一些东西..

时间戳(日期时间对象):UTC 所需显示:在特定时区

  • 设置xaxis_date()到您想要的显示时区(默认为 rcParam['timezone'] 对我来说是 UTC)

时间戳(日期时间对象):在特定时区 所需显示:在不同的特定时区

  • 为您的绘图函数 datetime 对象提供相应的时区 (tzinfo=)
  • 将 rcParams['timezone'] 设置为您想要的显示时区
  • 使用日期格式器(即使您对格式满意,the formatter is timezone aware)

如果您使用的是 plot_date(),您还可以传入 tz 关键字,但对于散点图,这是不可能的。

当您的源数据包含 unix 时间戳时,请务必明智地选择 datetime.datetime.utcfromtimestamp() 而没有 utc:fromtimestamp() 如果您要使用 matplotlib 时区功能。

这是我所做的实验(在本例中是在 scatter() 上),可能有点难以理解,但只是写在这里供所有关心的人使用。注意第一个点出现的时间(每个子图的 x 轴并不在同一时间开始): Different combinations of timezones

源代码:

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

关于python - 如何处理 Matplotlib 中带时区的时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22255356/

相关文章:

python - 获取 IOError : [Errno Invalid number of channels] -9998 when using mic with PyAudio on Raspberry Pi

python - 在不更改数据的情况下更改轴(Python)

python - 没有条目的 GTK3 组合框移动到有条目的 GTK3 组合框之后。为什么?

python - 在 matplotlib 中绘制 Needleman-Wunsch 成对序列比对的得分矩阵

python - 如何在 Python 中从离散数据集创建 3D 热图?

r - R 中的二维颜色渐变图

python - 在 Python 3.6 中使用 "or"或 "or-like"语句

python - 使用 "four"轴绘制 x-y 图

python - 从脚本中使用 Matplotlib 渲染器问题

r - 添加表格(对齐的文本 block )以在 R 中绘图