maulik mehta
maulik mehta

Reputation: 225

How to use datetime.time to plot

I have list of timestamps in the format of HH:MM:SS and want to plot against some values using datetime.time. Seems like python doesn't like the way I do it. Can someone please help ?

import datetime
import matplotlib.pyplot as plt

# random data
x = [datetime.time(12,10,10), datetime.time(12, 11, 10)]
y = [1,5]

# plot
plt.plot(x,y)
plt.show()

*TypeError: float() argument must be a string or a number*

Upvotes: 6

Views: 11354

Answers (3)

AstroFloyd
AstroFloyd

Reputation: 468

I came to this page because I have a similar issue. I have a Pandas DataFrame df with a datetime column df.dtm and a data column df.x, spanning several days, but I want to plot them using matplotlib.pyplot as a function of time of day, not date and time (datetime, datetimeindex). I.e., I want all data points to be folded into the same 24h range in the plot. I can plot df.x vs. df.dtm without issue, but I've just spent two hours trying to figure out how to convert df.dtm to df.time (containing the time of day without a date) and then plotting it. The (to me) straightforward solution does not work:

    df.dtm = pd.to_datetime(df.dtm)
    ax.plot(df.dtm,  df.x)
    # Works  (with times on different dates; a range >24h)

    df['time'] = df.dtm.dt.time
    ax.plot(df.time,  df.x)
    # DOES NOT WORK: ConversionError('Failed to convert value(s) to axis '
    matplotlib.units.ConversionError: Failed to convert value(s) to axis units:
    array([datetime.time(0, 0), datetime.time(0, 5), etc.])

This does work:

    pd.plotting.register_matplotlib_converters()  # Needed to plot Pandas df with Matplotlib
    df.dtm = pd.to_datetime(df.dtm, utc=True)     # NOTE: MUST add a timezone, even if undesired
    ax.plot(df.dtm,  df.x)
    # Works as before
    
    df['time'] = df.dtm.dt.time
    ax.plot(df.time,  df.x)
    # WORKS!!! (with time of day, all data in the same 24h range)

Note that the differences are in the first two lines. The first line allows better collaboration between Pandas and Matplotlib, the second seems redundant (or even wrong), but that doesn't matter in my case, since I use a single timezone and it is not plotted.

Upvotes: 1

michal.dul
michal.dul

Reputation: 175

It is still valid issue in Python 3.5.3 and Matplotlib 2.1.0.

A workaround is to use datetime.datetime objects instead of datetime.time ones:

import datetime
import matplotlib.pyplot as plt

# random data
x = [datetime.time(12,10,10), datetime.time(12, 11, 10)]
x_dt = [datetime.datetime.combine(datetime.date.today(), t) for t in x]
y = [1,5]

# plot
plt.plot(x_dt, y)
plt.show()

enter image description here

By deafult date part should not be visible. Otherwise you can always use DateFormatter:

import matplotlib.dates as mdates
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H-%M-%S'))

Upvotes: 4

user3666197
user3666197

Reputation: 1

Well, a two-step story to get 'em PLOT really nice

enter image description here

Step 1: prepare data into a proper format

from a datetime to a matplotlib convention compatible float for dates/times


As usual, devil is hidden in detail.

matplotlib dates are almost equal, but not equal:

#  mPlotDATEs.date2num.__doc__
#                  
#     *d* is either a class `datetime` instance or a sequence of datetimes.
#
#     Return value is a floating point number (or sequence of floats)
#     which gives the number of days (fraction part represents hours,
#     minutes, seconds) since 0001-01-01 00:00:00 UTC, *plus* *one*.
#     The addition of one here is a historical artifact.  Also, note
#     that the Gregorian calendar is assumed; this is not universal
#     practice.  For details, see the module docstring.

So, highly recommended to re-use their "own" tool:

from matplotlib import dates as mPlotDATEs   # helper functions num2date()
#                                            #              and date2num()
#                                            #              to convert to/from.

Step 2: manage axis-labels & formatting & scale (min/max) as a next issue

matplotlib brings you arms for this part too.

Check code in this answer for all details

Upvotes: 2

Related Questions