Skip to content

Need to register numpy's datetime64 in the units framework #1097

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
WeatherGod opened this issue Aug 17, 2012 · 11 comments
Closed

Need to register numpy's datetime64 in the units framework #1097

WeatherGod opened this issue Aug 17, 2012 · 11 comments

Comments

@WeatherGod
Copy link
Member

I just remembered that this was a special request by John Hunter back during SciPy 2012 conference. He says that he considers this a release-stopper until we get this added in.

@efiring
Copy link
Member

efiring commented Aug 17, 2012

@mdboom, supporting datetime64 looks like a substantial chunk of work to do well--with lots of testing. Ideally, I suspect we would want it to be handled somewhat interchangeably with the regular datetime objects we already support. Given that datetime64 was primitive--perhaps broken--in numpy 1.6, and is marked "experimental" in numpy 1.7, I don't think it should be a blocker for mpl 1.2; I think it would be a better target for 1.3. Your call, though.

@mdboom
Copy link
Member

mdboom commented Aug 17, 2012

Given that the 1.2 freeze is scheduled for Monday, August 20, I think there's not much chance of it getting in 1.2 without pushing the timeline back.

I haven't looked at this issue at all, so have no sense of its scope. @efiring's summary of the status in Numpy suggests that there's no real rush.

@mdboom
Copy link
Member

mdboom commented Aug 19, 2012

I've spent some time with this -- it looks like the minimal option is to make datetime64 work more-or-less like the datetime support we have now, and assume a minimum resolution of 1s etc. But the right thing to do is to natively support all of the different bases that datetime64 supports without losing resolution. That's going to be considerable effort I think -- I'm somewhat handicapped by not having a good understanding of the units framework and how data flows around through it. I think we put this off in order to do it right.

@efiring
Copy link
Member

efiring commented Aug 19, 2012

On 2012/08/19 7:51 AM, Michael Droettboom wrote:

I think we put this off in order to do it right.

+1

@pelson
Copy link
Member

pelson commented Aug 19, 2012

Removed from the 1.2.x milestone. FYI I will be needing to look at datetime handling in the not-too-distant future (at least the next 6 months anyway) to support other calendar types (360 day calendars for instance).

@tacaswell
Copy link
Member

@pelson @mdboom Any updates on this?

@WeatherGod
Copy link
Member Author

Just to give this issue a bit of a kick in the pants, here is a prototype as suggested by @agijsberts

from matplotlib import units, dates
from matplotlib import pyplot as plt
from numpy import datetime64, timedelta64, arange, ndarray, dtype
from numpy.random import rand
import datetime

resolution_scale = {
    dtype('datetime64[ns]'): 1e-9,
    dtype('datetime64[us]'): 1e-6,
    dtype('datetime64[ms]'): 1e-3,
    dtype('datetime64[s]'): 1,
    dtype('datetime64[m]'): 60,
    dtype('datetime64[h]'): 60 * 60,
    dtype('datetime64[D]'): 24 * 60 * 60,
}

class Datetime64Converter(dates.DateConverter):
    @staticmethod
    def convert(values, unit, axis):
        if isinstance(values, ndarray) and issubclass(values.dtype.type, datetime64):
            return dates.epoch2num(values.view('i8') * resolution_scale[values.dtype])
        elif isinstance(values, datetime.date):
            return dates.date2num(values)
        else:
            return values

units.registry[datetime64] = Datetime64Converter

a = arange('2014-01-01', '2014-01-07', timedelta64(1, 'D'), dtype='datetime64[D]')
b = rand(len(a))
for i, r in enumerate(('ns', 'us', 'ms', 's', 'm', 'h', 'D')):
    plt.plot(a.astype('datetime64[{0}]'.format(r)), b + i, label=r)
plt.legend()
plt.show()

It has limitations, but it would be a step up from where we are now.

@pelson
Copy link
Member

pelson commented Dec 3, 2014

For the record, @jorisvandenbossche implemented a similar piece of functionality in pandas: pandas-dev/pandas#8693

@jorisvandenbossche
Copy link

And for clarity, I did not really implement something new, I only registered the existing pandas machinery also for the datetime64 dtype.
(previously, it was only registered for the datetime.datetime/date/time types and for the pandas Timestamp type).

But, the pandas implementation can certainly be used as a start / inspiration to implement this in matplotlib (it should be investigated how much of the implementation is pandas specific, but based on the discussion here (pandas-dev/pandas#8614 (comment)) that is maybe not too much).

@agijsberts
Copy link

To clarify, the implementation currently in pandas only supports datetime64[ns] and is thus more limited than the prototype, which supports different resolution scales. I think the most straightforward solution would therefore be to let matplotlib register a generic datetime64 converter (like the prototype) and then remove the registration from pandas. Obviously, pandas would still be responsible for handling its native types (DatetimeIndex, Timestamp, etc.).

@tacaswell
Copy link
Member

Closing as I think we should, to first order, delegate all the datetime64 handling to pandas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants