How to handle time with timezone in Matplotlib?

I have data points whose abscissas are datetime.datetime objects with a time zone (their tzinfo turns out to be bson.tz_util.FixedOffset received via MongoDB).

When I draw them using scatter() , what is the time zone of label shortcuts?

Changing timezone in matplotlibrc does not change anything on the displayed chart (I must have misunderstood the discussion of time zones in the Matplotlib documentation).

I experimented a bit with plot() (instead of scatter() ). If a single date is specified, it displays it and ignores the time zone. However, when multiple dates are set, it uses a fixed time zone, but how is it determined? I can not find anything in the documentation.

Finally, is plot_date() supposed to be the solution to these timezone problems?

+6
source share
1 answer

The issue has already been considered in the form of comments. However, I was still struggling with time zones. To understand this, I tried all the combinations. I think that you have two main approaches, depending on whether your datetime objects are already in the right time zone or are in another time zone, I tried to describe them below. Maybe I still missed / mixed something.

Timestamps (datetime objects): in UTC; Desired display: in a specific time zone

  • Set xaxis_date () to the desired time zone of the display (by default for rcParam['timezone'] , which was UTC for me)

Timestamps (datetime objects): in a specific time zone Desired display: in another specific time zone

  • Feed your objects to the datetime function of the graph function with the appropriate time zone ( tzinfo= )
  • Set rcParams ['Time Zone "] to the desired time zone.
  • Use the dateformatter format (even if you are satisfied with the format, the formatter is notified of the time zone )

If you use plot_date (), you can also pass the tz keyword, but this is not possible for a scatter plot.

When your source data contains unix timestamps, make sure that you choose wisely from datetime.datetime.utcfromtimestamp() and without utc: fromtimestamp() if you intend to use the matplotlib timezone features.

This is an experiment that I did (in this case, the scatter ()), it is a bit complicated, perhaps, but just written here for all who care. Note the time at which the first points appear (the x axis does not start at the same time for each subtitle): Different time zone combinations

Source:

 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() 
+5
source

All Articles