Matplotlib Date Precision and Epochs

PythonPythonBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

This is a step-by-step lab that demonstrates how to handle date precision and epochs in Matplotlib. Matplotlib can work with .datetime objects and numpy.datetime64 objects using a unit converter that recognizes these dates and converts them to floating point numbers. Before Matplotlib 3.3, the default for this conversion returns a float that was days since "0000-12-31T00:00:00". As of Matplotlib 3.3, the default is days from "1970-01-01T00:00:00". This allows more resolution for modern dates.

VM Tips

After the VM startup is done, click the top left corner to switch to the Notebook tab to access Jupyter Notebook for practice.

Sometimes, you may need to wait a few seconds for Jupyter Notebook to finish loading. The validation of operations cannot be automated because of limitations in Jupyter Notebook.

If you face issues during learning, feel free to ask Labby. Provide feedback after the session, and we will promptly resolve the problem for you.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL matplotlib(("`Matplotlib`")) -.-> matplotlib/BasicConceptsGroup(["`Basic Concepts`"]) matplotlib(("`Matplotlib`")) -.-> matplotlib/PlottingDataGroup(["`Plotting Data`"]) python(("`Python`")) -.-> python/ControlFlowGroup(["`Control Flow`"]) python(("`Python`")) -.-> python/DataStructuresGroup(["`Data Structures`"]) python(("`Python`")) -.-> python/ModulesandPackagesGroup(["`Modules and Packages`"]) python(("`Python`")) -.-> python/PythonStandardLibraryGroup(["`Python Standard Library`"]) python(("`Python`")) -.-> python/DataScienceandMachineLearningGroup(["`Data Science and Machine Learning`"]) python(("`Python`")) -.-> python/FunctionsGroup(["`Functions`"]) matplotlib/BasicConceptsGroup -.-> matplotlib/importing_matplotlib("`Importing Matplotlib`") matplotlib/BasicConceptsGroup -.-> matplotlib/figures_axes("`Understanding Figures and Axes`") matplotlib/PlottingDataGroup -.-> matplotlib/line_plots("`Line Plots`") python/ControlFlowGroup -.-> python/for_loops("`For Loops`") python/ControlFlowGroup -.-> python/list_comprehensions("`List Comprehensions`") python/DataStructuresGroup -.-> python/lists("`Lists`") python/DataStructuresGroup -.-> python/tuples("`Tuples`") python/ModulesandPackagesGroup -.-> python/importing_modules("`Importing Modules`") python/ModulesandPackagesGroup -.-> python/standard_libraries("`Common Standard Libraries`") python/PythonStandardLibraryGroup -.-> python/date_time("`Date and Time`") python/DataScienceandMachineLearningGroup -.-> python/numerical_computing("`Numerical Computing`") python/DataScienceandMachineLearningGroup -.-> python/data_visualization("`Data Visualization`") python/FunctionsGroup -.-> python/build_in_functions("`Build-in Functions`") subgraph Lab Skills matplotlib/importing_matplotlib -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} matplotlib/figures_axes -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} matplotlib/line_plots -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} python/for_loops -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} python/list_comprehensions -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} python/lists -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} python/tuples -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} python/importing_modules -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} python/standard_libraries -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} python/date_time -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} python/numerical_computing -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} python/data_visualization -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} python/build_in_functions -.-> lab-48655{{"`Matplotlib Date Precision and Epochs`"}} end

Import necessary packages

The first step is to import the necessary packages, including datetime, matplotlib.pyplot, and numpy.

import datetime
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates

Set epoch to the old default

The next step is to set the epoch to the old default, which is days since "0000-12-31T00:00:00". This is done using the mdates.set_epoch method.

mdates.set_epoch('0000-12-31T00:00:00')

Convert datetime to matplotlib date

Now that the epoch has been set, we can convert a datetime object to a Matplotlib date using the mdates.date2num function.

date1 = datetime.datetime(2000, 1, 1, 0, 10, 0, 12, tzinfo=datetime.timezone.utc)
mdate1 = mdates.date2num(date1)

Round-trip the date

We can then round-trip the date using the mdates.num2date function to make sure the conversion is accurate.

date2 = mdates.num2date(mdate1)

Set epoch to the new default

To use modern dates at microsecond precision, we need to set the epoch to the new default, which is days since "1970-01-01T00:00:00".

mdates.set_epoch('1970-01-01T00:00:00')

Convert datetime to matplotlib date with new epoch

Now that the epoch has been set to the new default, we can convert a datetime object to a Matplotlib date using the mdates.date2num function.

date1 = datetime.datetime(2020, 1, 1, 0, 10, 0, 12, tzinfo=datetime.timezone.utc)
mdate1 = mdates.date2num(date1)

Round-trip the date with new epoch

We can then round-trip the date using the mdates.num2date function to make sure the conversion is accurate.

date2 = mdates.num2date(mdate1)

Convert numpy.datetime64 to matplotlib date

numpy.datetime64 objects have microsecond precision for a much larger timespace than .datetime objects. However, currently, Matplotlib time is only converted back to datetime objects, which have microsecond resolution and years that only span 0000 to 9999.

date1 = np.datetime64('2000-01-01T00:10:00.000012')
mdate1 = mdates.date2num(date1)

Plotting

This step demonstrates how the epoch affects plotting. With the old default epoch, the times were rounded during the internal date2num conversion, leading to jumps in the data.

mdates.set_epoch('0000-12-31T00:00:00')

x = np.arange('2000-01-01T00:00:00.0', '2000-01-01T00:00:00.000100', dtype='datetime64[us]')
xold = np.array([mdates.num2date(mdates.date2num(d)) for d in x])
y = np.arange(0, len(x))

fig, ax = plt.subplots(layout='constrained')
ax.plot(xold, y)
ax.set_title('Epoch: ' + mdates.get_epoch())
ax.xaxis.set_tick_params(rotation=40)
plt.show()

For dates plotted using the more recent epoch, the plot is smooth:

mdates.set_epoch('1970-01-01T00:00:00')

fig, ax = plt.subplots(layout='constrained')
ax.plot(x, y)
ax.set_title('Epoch: ' + mdates.get_epoch())
ax.xaxis.set_tick_params(rotation=40)
plt.show()

Summary

This lab demonstrates how to handle date precision and epochs in Matplotlib. We can set the epoch to the old default or the new default using the mdates.set_epoch method. We can then convert datetime or numpy.datetime64 objects to Matplotlib dates using the mdates.date2num function, and round-trip the dates using the mdates.num2date function to make sure the conversion is accurate. We can also plot data with different epochs to observe the differences in the plot.

Other Python Tutorials you may like