Stream: python-questions

Topic: cftime and matplotlib


view this post on Zulip Stephen Yeager (Jan 31 2023 at 22:27):

I'm trying to generate a line plot of an xarray DataArray whose time coordinate is in cftime.DatetimeNoLeap. Matplotlib pyplot.plot returns an error message. This notebook used to work, but I've updated my environment (now using matplotlib v3.6.3, xarray v2023.1.0, cftime v1.6.2) and now it doesn't. Here is the cell that fails:

fig = plt.figure(figsize=(5,5))
ax1 = fig.add_subplot(2,1,1)
ax1.plot(obs_reg1sst.time,obs_reg1sst,color='k',marker='.',markersize=6,label='OBS')

The error message is: TypeError: float() argument must be a string or a real number, not 'cftime._cftime.DatetimeNoLeap'

I haven't found any relevant information after a google search, so any help would be much appreciated.

view this post on Zulip Keith Lindsay (Jan 31 2023 at 22:45):

Here's a function that I've previously used to convert time values into a numpy array with units of year, which are usable in plotting functions:

def time_year_plus_frac(ds, time_name):
    """return time variable, as numpy array of year plus fraction of year values"""

    # this is straightforward if time has units='days since 0000-01-01' and calendar='noleap'
    # so convert specification of time to that representation

    # get time values as an np.ndarray of cftime objects
    if np.dtype(ds[time_name]) == np.dtype("O"):
        tvals_cftime = ds[time_name].values
    else:
        tvals_cftime = cftime.num2date(
            ds[time_name].values,
            ds[time_name].attrs["units"],
            ds[time_name].attrs["calendar"],
        )

    # convert cftime objects to representation mentioned above
    tvals_days = cftime.date2num(
        tvals_cftime, "days since 0000-01-01", calendar="noleap"
    )

    return tvals_days / 365.0

If you replace obs_reg1sst.time with time_year_plus_frac(obs_reg1sst, "time"), you might be in business (after importing cftime, and numpy as np). The function is written to work if ds.time has been converted to cftime objects or not.

view this post on Zulip Stephen Yeager (Jan 31 2023 at 23:55):

Thanks Keith. Looks like this function will help me avoid the issue, but I'm left wondering why this cftime/matplotlib incompatibility comes and goes.

view this post on Zulip Katie Dagon (Feb 01 2023 at 00:00):

@Stephen Yeager have you ever tried using nc-time-axis? In the past it has helped me with cftime/matplotlib issues

view this post on Zulip Stephen Yeager (Feb 01 2023 at 00:10):

@Katie Dagon Thanks very much for that suggestion! Plot works fine after importing nc-time-axis.

view this post on Zulip Notification Bot (Feb 01 2023 at 02:50):

Deepak Cherian has marked this topic as resolved.

view this post on Zulip David Bailey (Jun 15 2023 at 15:47):

So, was nc-time-axis added to the NPL environment? Who should we contact to make this happen?

view this post on Zulip Katie Dagon (Jun 15 2023 at 22:21):

@David Bailey It looks like you can check packages in NPL using conda list --name npl-2023a (after module load conda).
I do see nc-time-axis version 1.4.1 listed under npl-2023a.

view this post on Zulip David Bailey (Jun 16 2023 at 16:00):

Thanks for this. However, this is still not working for me. I import nc_time_axis and it still gives me the error:

ValueError: The values must be numbers or instances of "nc_time_axis.CalendarDateTime" or "cftime.datetime".

From our netCDF files time is cftime.datetimeNoLeap. Is there another conversion I am missing?

view this post on Zulip Katie Dagon (Jun 20 2023 at 15:38):

Is this an error at the import step or later on?

view this post on Zulip Notification Bot (Jun 20 2023 at 16:21):

Deepak Cherian has marked this topic as unresolved.

view this post on Zulip Deepak Cherian (Jun 20 2023 at 16:21):

A full error message would be useful.

view this post on Zulip David Bailey (Jun 20 2023 at 17:29):

@Michael Levy helped me figure this out. I was trying to adjust the xticks manually and the syntax does not work with the cftime object. Once I removed the xticks statement, it works perfectly!


Last updated: May 16 2025 at 17:14 UTC