-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
provide converters for datetime64 types #9610
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
Comments
Hmm, actually seems to be because the units aren't being converted by the call to |
The issue is this line: matplotlib/lib/matplotlib/axes/_axes.py Line 5248 in b0a0a8e
Running a |
Thats a bother. Particularly as we don't like A fix is to check for Another fix is for the units registry to recognize |
Pandas does it in their registry code: link def register():
units.registry[lib.Timestamp] = DatetimeConverter()
units.registry[Period] = PeriodConverter()
units.registry[pydt.datetime] = DatetimeConverter()
units.registry[pydt.date] = DatetimeConverter()
units.registry[pydt.time] = TimeConverter()
units.registry[np.datetime64] = DatetimeConverter() so I'm wondering if this is an upstream fix that needs to happen on their end... |
@story645 Hmmm, very confused. Do we call their converter? It looks like they rewrote matplotlib's for their plotting? |
No, I don't think so, though we refer to their converter as a good way to get from I wonder why we don't just use this ourselves? |
The point is that they used to register their converter when pandas was imported; now they do it only when they need it for their plotting. This makes sense in that having our code changed by the simple act of importing pandas is intrusive. |
The don't only import it on plotting because they import their convertor in their timeseries code from pandas.plotting._converter import (register, time2num,
TimeConverter, TimeFormatter,
PeriodConverter, get_datevalue,
DatetimeConverter,
PandasAutoDateFormatter,
PandasAutoDateLocator,
MilliSecondLocator, get_finder,
TimeSeries_DateLocator,
TimeSeries_DateFormatter) so I think we're still hitting it. Otherwise I think plotting would be totally broken for pandas timeseries objects if not done through their plotting api. Eta: matplotlib's dates.py only supports datetime objects units.registry[datetime.date] = DateConverter()
units.registry[datetime.datetime] = DateConverter() |
OK, I'm slowly understanding... I run import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
time = pd.date_range('2000-01-01', periods=20)
depth = np.arange(20)
data = np.random.rand(20, 20)
fig, ax = plt.subplots()
ax.pcolormesh(time, depth, data) For pandas-0.20 things run fine, and the units registry has keys:
For pandas-0.21, we get the error, and the units registry only has keys:
If I include import pandas.plotting._converter as pandacnv
pandacnv.register() then I get back the pandas stuff and the example runs fine.
So, as @efiring said, what happened here was that pandas 0.21 moved the import of their registers out of the base import, and into their plotting area. More to the point, they now explicitly require the call of FWIW, our pandas-0.21 plotting is indeed broken for other examples: import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
time = pd.date_range('2000-01-01', periods=20)
depth = np.arange(20)
data = np.random.rand(20, 20)
fig, ax = plt.subplots()
ax.plot(time, data[3,:])
plt.show() ... doesn't outright fail but gets: Whereas it is decoded correctly in pandas-0.20. |
Yeah, from pandas.plotting import _converter
_converter.register() # needs to override so set_xlim works with str/number But that was removed in 0.21 (pandas-dev/pandas#17710) Not at all sure what to do here.
Option 1 May break examples and code that didn't load pandas. |
See also pandas-dev/pandas#18153 Looks like the advice there (@TomAugspurger) is to use the extra verbiage. |
I'm not sure how to do one without making pandas an optional dependency of matplotlib, unless the plan is to only do it in tests. looks like in #18153 that their plan is to eventually basically implement 2. |
Sorry about the headaches here. If matplotlib is willing to accept it, I can put in the work to port the relevant bits of https://github.com/pandas-dev/pandas/blob/8dac633142daa8d5bcd0cf77ad89b97628d474eb/pandas/plotting/_converter.py over to matplotlib. Basically: does NumPy want a formatter, locator, etc. for datetime64s? Would adding that formatter be considered an API change that people would need to opt in to? |
@TomAugspurger. No problem! Most of the flail on my part was just not knowing what was going on After thinking about it I realized what @efiring said above is absolutely correct and what you did in pandas is correct. Import pandas should not have silently registered new units for exactly the reason that it’s very confusing. I changed the tests that depend on pandas to simply call register With respect to datetime64 I personally think adding that would be fabulous. I do wonder about taking a step backwards and deciding what to do about matplotlibs date handling. One could even imagine moving the date handling out of pandas altogether and having what pandas has as the matpltolib default or at least the non pandas dependent parts. |
But I think kind of the point of the units framework is to silently handle library specific data types so the user doesn't explicitly have to deal with it. In this case, moving the code to mpl kind of makes sense because matplotlib imports numpy, but then what's the solution for datatypes matplotlib doesn't import? |
@story645 So you think pandas should keep the Right now we silently register our date handling and categoricals. I can see your point, but I actually think it makes things confusing. How do I know, as a user, what units handling is present? Right now, using pandas 0.20, I have no idea what the units handling and tick handling etc is for a Ref #9713 |
I dunno honestly. I agree that pandas shouldn't have a required mpl dependency, so I understand why they don't want it in their top-level import path, but I also think it's unwieldy to require
I sort of think that's a fair point, except I'm not sure non-dev users would care, and Pandas doesn't register the same datatypes as data.py so devs can easily find the answer.
My very first patch was for scikits-timeseries in like 2011, so I remember too. But it's gotten way way better, in large part 'cause of pandas and the stuff it does semi-automagically. |
FWIW, the change in pandas 0.21.0 was to not do a Not registering the converters is a side-effect of that change. I think it's for the best. We've had questions in the past about "why does importing pandas mess up my plots, when I don't even use it. Now we just have questions on the other side :) And, I think moving pandas' locator / converter for datetimes to matplotlib would be a good thing, so that everyone benefits from them, not just pandas. |
@TomAugspurger I personally agree - for now we need to add a specific I think a PR to add more date handling would be most welcome, but its not urgent (i.e. would likely be a 2.2 milestone) I'm not particularly happy with the units/converter handling as it is now (see #9713) but that seems a bigger issue. I think advice from the pandas side would be very helpful as your use of this framework is very complete and seems very robust. |
Agree here, but what happens to the pandas specific data types? |
Is there a reason this is closed? |
Accidentally/automagically 'cause #9726 got merged and fixes it on the test side. |
What is the remaining issue? |
That import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
time = pd.date_range('2000-01-01', periods=20)
depth = np.arange(20)
data = np.random.rand(20, 20)
fig, ax = plt.subplots()
ax.plot(time, data[3,:])
plt.show() doesn't work without manually registering pandas' converter. (I just spent a while trying to work out why basically all my plotting code was broken before realising it was this bug) |
MPL never handled registering the pandas units converter. It was pandas in |
I agree it's in our court, but I also think that doing |
I think this should be re-framed as datetime64 support in mpl, not pandas support. Pandas uses one very restricted flavor of datetime64. |
Changed the title, moved to 2.2 and updated the labels. |
There actually already was an issue for "datetime64 support in mpl": #1097, and which was closed recently deferring to pandas ... (but of course, situation has changed in the meantime)
@TomAugspurger I also once looked at it, and think agree with this that it is not that easy to port the full pandas functionality (although it is a long time ago). |
FYI, given the many feedback we got about this, we are considering on the pandas side to temporarily undo this change in the upcoming bug fix release to have a smoother deprecation period of the automatic registering of our converters: pandas-dev/pandas#18301 |
Closed by #9779 |
See https://travis-ci.org/matplotlib/matplotlib/jobs/294376461#L2096 for more details
The text was updated successfully, but these errors were encountered: