Search code examples
pythondatetimematplotlibtimezonepytz

Creating datetime objects in UTC without timezone that can be imported by Matplotlib


I have a list of datetime objects which are created this way:

from datetime import datetime
import pytz

_year = 2018
_month = 2
_day = 3
_hour = 14
_minute = 30
csv_timezone = pytz.timezone('Europe/Berlin')

csv_dt = datetime(_year, _month, _day, _hour, _minute)
print('csv_dt')
print(csv_dt)

Which later I want to consume in UTC for Matplotlib:

utc_dt = csv_timezone.localize(csv_dt).astimezone(pytz.utc)
print('utc_dt')
print(utc_dt)

The result is as follows:

csv_dt
2018-02-03 14:30:00
utc_dt
2018-02-03 13:30:00+00:00

As stated before, I want to use those objects in Matplotlib. Which, as per documentation, expects the following datetime object:

Date formatting Commonly, in Python programs, dates are represented as datetime objects, so we have to first convert other data values into datetime objects, sometimes by using the dateutil companion module, for example:

import datetime

date = datetime.datetime(2009, 03, 28, 11, 34, 59, 12345)

or

import dateutil.parser

datestrings = ['2008-07-18 14:36:53.494013','2008-07-2014:37:01.508990', '2008-07-28 14:49:26.183256']

dates = [dateutil.parser.parse(s) for s in datestrings]

Once we have the datetime objects, in order to let Matplotlib use them, we have to convert them into floating point numbers that represent the number of days since 0001-01-01 00:00:00 UTC.

To do that, Matplotlib itself provides several helper functions contained in the matplotlib.dates module:

• date2num(): This function converts one or a sequence of datetime objects to float values representing days since 0001-01-01 00:00:00 UTC (the fractional parts represent hours, minutes, and seconds)

(Excerpt from Matplotlib for Python Developers, Sandro Tosi, Ed. PACKT PUBLISHING 2009. Page 95)

So I do not understand why the datetime object date2num function is expecting has the following form:

2008-07-20 14:37:01.508990

While the one I am generating has this form:

2018-02-03 13:30:00+00:00

The error I am getting is:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-7d0a84cb48da> in <module>
     20 
     21 # Convert to matplotlib required
---> 22 mpl_times =  mpl.dates.date2num(times)
     23 
     24 plt.figure()

times is:

<class 'numpy.ndarray'>
times
['2018-01-12 07:00:00+01:00', '2018-01-12 07:01:00+01:00', '2018-01-12 07:02:00+01:00' ..... ]

How could I convert from my format to the format expected by date2num?


Solution

  • How do you import matplotlib.dates? Can you try

        from matplotlib import dates as dt
        ....
        ....
        mpl_times =  dt.date2num(times)
    

    The following code works for me

        from datetime import datetime
        import pytz
        from matplotlib import dates as dt
    
        _year = 2018
        _month = 2
        _day = 3
        _hour = 14
        _minute = 30
        csv_timezone = pytz.timezone('Europe/Berlin')
    
        csv_dt = datetime(_year, _month, _day, _hour, _minute)
        print('csv_dt')
        print(csv_dt)
    
        utc_dt = csv_timezone.localize(csv_dt).astimezone(pytz.utc)
        print('utc_dt')
        print(utc_dt)
        print (dt.date2num(utc_dt))
    

    The output is 736728.5625