-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
ENH: add rcParam for ConciseDate and interval_multiples #17022
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
ENH: add rcParam for ConciseDate and interval_multiples #17022
Conversation
lib/matplotlib/dates.py
Outdated
units.registry[datetime.date] = DateConverter() | ||
units.registry[datetime.datetime] = DateConverter() | ||
|
||
def register_converters(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic should really be in a _validate_date_converter
validator, no? otherwise that means that setting the rcParam from anywhere but the matplotlibrc would have no effect.
(And yes, that means we may either need to try to import matplotlib.dates in rcsetup, or, if that's not possible, special case initial import time and re-validate once we import matplotlib.dates).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does a validator get called every time the rcParam
dict is updated? I guess that would be a good way to do that, if a little magical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there an easy way to tell if the validation is the initial one or a subsequent one? Because if not, I'm not convinced this is worth the bother.
I agree this seems reasonable, but share @anntzer 's concern that as written it won't trigger when the rcparams are changed. |
Unless someone has a straightforward way to update the converter during the init of the rcParams without importing datetime, I'm not convinced the magic of being able to change the rcParam on the fly is worthwhile. People can just call the new |
ok, but in that case you need at least to block updating of the rcParam once matplotlib is imported (again, with a custom validator) (and even then I doubt I'd accept the feature). I don't like that solution but I think it's expected (well, at least I expect) that setting a variable in the matplotlibrc is equivalent to setting it in python code, so if it's not at least it should error out cleanly. |
Well again is there an easy way to know if the validator is being run for first time? If not I don’t see how this can work. Frankly I think the magic imbued in rcParams is needlessly complicated and we should not think of it as something that must allow real time toggles for everything. |
It's not so much called once as called from the matplotlibrc, I'm sure the right amount of stack walking could work. |
OK, not ridiculously ugly. I just bail if the matplotlib.dates import fails... |
Much better :) |
1a6da7b
to
0b05b77
Compare
d22ebe4
to
f2a84b1
Compare
f2a84b1
to
e4c7774
Compare
... I forgot about this one. Its now rebased and should be ready for review... |
6cb6516
to
22923c5
Compare
lib/matplotlib/dates.py
Outdated
|
||
class _rcParam_helper: | ||
""" | ||
Never instatiated, but manages the rcParams for dates... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps merge the comment above and the docstring...
lib/matplotlib/dates.py
Outdated
converter = DateConverter | ||
|
||
interval_multiples = cls.int_mult | ||
print(interval_multiples) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooops
lib/matplotlib/dates.py
Outdated
|
||
interval_multiples = cls.int_mult | ||
print(interval_multiples) | ||
units.registry[np.datetime64] = converter( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps just instantiate a single converter and assign to all 3?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... I guess so? the old code instantiated three converters, so I'm a little hesitant. OTOH, I'm not sure why it did, and I don't think we lose any flexibility this way...
lib/matplotlib/rcsetup.py
Outdated
try: | ||
import matplotlib.dates as mdates | ||
mdates._rcParam_helper.set_converter(s) | ||
except Exception as e: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a comment that this can only fail at initial import time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah - so this gives me a bit of pause. Does this cause any import slowdowns?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you could write mdates = sys.modules.get("matplotlib.dates"); if mdates: ...
as matplotlib.dates will be in sys.modules once everything is set up properly...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I prefer that....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jklymak do you still want to change how this is written?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs perhaps a few comments/docstring fixes, but other than that looks fine to me.
6b6f120
to
2cdcfe7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add doc in ConciseDateFormatter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modulo a example with a plot in the whats new.
lib/matplotlib/dates.py
Outdated
@@ -1884,17 +1888,19 @@ class ConciseDateConverter(DateConverter): | |||
# docstring inherited | |||
|
|||
def __init__(self, formats=None, zero_formats=None, offset_formats=None, | |||
show_offset=True): | |||
show_offset=True, interval_multiples=True): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kwonly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure
lib/matplotlib/dates.py
Outdated
@@ -1832,8 +1832,11 @@ class DateConverter(units.ConversionInterface): | |||
The 'unit' tag for such data is None or a tzinfo instance. | |||
""" | |||
|
|||
@staticmethod | |||
def axisinfo(unit, axis): | |||
def __init__(self, interval_multiples=True): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kwonly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure
plt.rcParams['date.converter'] = 'auto' | ||
plt.rcParams['date.interval_multiples'] = False | ||
ax = axs[1] | ||
ax.plot(dates, y) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This renders as https://39494-1385122-gh.circle-artifacts.com/0/doc/build/html/users/next_whats_new/rcparams_dates.html I'm forgetting how to get the plot to show in the docs? OK figured it out
dfd8924
to
4f29425
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still approve, leave it to @jklymak if we should change how the conditional import is done.
Anyone can merge.
4f29425
to
abc06c5
Compare
Ooops, duh - I missed one of the two cases. Thanks for pointing that out. |
abc06c5
to
610f5fb
Compare
610f5fb
to
a793bde
Compare
PR Summary
This is a proposal for two new
date
rcParam entries:date.converter
which takes a string. If its'concise'
thenmdates.ConciseDateConverter
is used for dates, otherwisemdates.AutoDateConverter
is used (as before). Default is the same as before: 'auto'date.interval_multiples
sets whether 'interval_multiples' is used (True by default) for the auto locators.Note this needs a newEDIT: fixed to allow automatic changing of the rcParams....mdates.register_converters
to work aftermatplotlib.dates
has been imported bymatplotlib.pyplot
.Needs tests and a what's new...
PR Checklist