Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Bug]: Matplotlib date formatter and cftime and pandas incompatible ? #24951

@oliviermarti

Description

@oliviermarti

Bug summary

DateFormatter produces wrong values for a time axis with cftimevalues

Code for reproduction

# Needed modules
import xarray as xr
import cftime, matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter, YearLocator
import nc_time_axis

# Open data on ESGF server
d_tas = xr.open_dataset ("https://vesg.ipsl.upmc.fr/thredds/dodsC/cmip5/output1/IPSL/IPSL-CM5A-LR/rcp85/day/atmos/day/r1i1p1/v20111103/tas/tas_day_IPSL-CM5A-LR_rcp85_r1i1p1_20060101-22051231.nc", decode_times=True, use_cftime=True)

# Define variable
tas = d_tas['tas'][0:800,34,45].squeeze()

# A few checks
print ( tas.time.values[0] )
print ( tas.time.attrs )

# Plots
fig, axs = plt.subplots (nrows=2, ncols=2, figsize=(10,10) )
axs=axs.ravel()

## Very simple plot
ax = axs[0]
ax.plot ( tas.time, tas )
ax.set_title ( 'Correct plot \nCorrect time axis')

## Add formatting : \!/ Time axis is shifted
ax = axs[1]
ax.plot ( tas.time, tas )
ax.xaxis.set_major_formatter ( DateFormatter ('%Y-%M'))
ax.set_title ( 'Bug using DateFormatter \nTime axis is shifted by about 30 years')

## Solution using nc_time_axis
ax = axs[2]
ax.plot ( tas.time, tas )
formatter = nc_time_axis.CFTimeFormatter ("%Y-%m", "noleap")
ax.xaxis.set_major_formatter ( formatter )
ax.set_title ( 'Solution using nc_time_axis')

plt.savefig ('BugMplCftime.png')

Actual outcome

The first, simple, plot is correct.

The second plot uses DateFormatter. The time labels are wrong by about 30 years. I'm very puzzled, and don't know it is a matplotlib or a cftime issue ?

The third plot use nc-time-axis to correct the time axis values. Solution suggested by @spencerkclark (in Unidata/cftime issue #303 Unidata/cftime#303) and independantly by @jypeter.

Sea nc-time-axis at https://nc-time-axis.readthedocs.io/en/latest/

Expected outcome

Matplotlib should at least raise an error when meeting object that it can not handle properly

If it could produces correct labels, it will be nice !

Additional information

  • Do you maybe even know a fix?
    Using nc_time_axis. See above.

Operating system

OS/X

Matplotlib Version

3.6.1

Matplotlib Backend

Qt5Agg

Python version

3.10.8

Jupyter version

3.4.8

Installation

conda

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions