-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
API: Change matplotlib formatter registration #28722
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
Changes from 5 commits
afb6aaa
b9346a8
c6da330
cb4adb4
2e5b290
8e97c14
5849bad
7c40a41
3f04c9c
b177576
92b9f00
d7d0dba
ea61e6f
78a35a4
db648da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import contextlib | ||
import datetime as pydt | ||
from datetime import datetime, timedelta | ||
import warnings | ||
import functools | ||
|
||
from dateutil.relativedelta import relativedelta | ||
import matplotlib.dates as dates | ||
|
@@ -23,6 +24,7 @@ | |
) | ||
from pandas.core.dtypes.generic import ABCSeries | ||
|
||
from pandas import get_option | ||
import pandas.core.common as com | ||
from pandas.core.index import Index | ||
from pandas.core.indexes.datetimes import date_range | ||
|
@@ -39,7 +41,6 @@ | |
|
||
MUSEC_PER_DAY = 1e6 * SEC_PER_DAY | ||
|
||
_WARN = True # Global for whether pandas has registered the units explicitly | ||
_mpl_units = {} # Cache for units overwritten by us | ||
|
||
|
||
|
@@ -55,13 +56,43 @@ def get_pairs(): | |
return pairs | ||
|
||
|
||
def register(explicit=True): | ||
# Renamed in pandas.plotting.__init__ | ||
global _WARN | ||
def pandas_converters_deco(func): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason why this needs to be a decorator? Perhaps a style preference but I would find it easier to grok if the context manager was used where required in the actual plotting methods There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need. I mainly did it for a smaller diff / less indentation :) Happy to go either way here.
TomAugspurger marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
Decorator applying pandas_converters. | ||
""" | ||
|
||
@functools.wraps(func) | ||
def wrapper(*args, **kwargs): | ||
with pandas_converters(): | ||
return func(*args, **kwargs) | ||
|
||
if explicit: | ||
_WARN = False | ||
return wrapper | ||
|
||
|
||
@contextlib.contextmanager | ||
def pandas_converters(): | ||
""" | ||
Context manager registering pandas' converters for a plot. | ||
|
||
When | ||
TomAugspurger marked this conversation as resolved.
Show resolved
Hide resolved
|
||
See Also | ||
-------- | ||
pandas_converters_deco : Decorator that applies this. | ||
""" | ||
value = get_option("plotting.matplotlib.register_converters") | ||
|
||
if value: | ||
# register for True or "auto" | ||
register() | ||
try: | ||
yield | ||
finally: | ||
if value == "auto": | ||
# only deregister for "auto" | ||
deregister() | ||
|
||
|
||
def register(): | ||
pairs = get_pairs() | ||
for type_, cls in pairs: | ||
# Cache previous converter if present | ||
|
@@ -86,24 +117,6 @@ def deregister(): | |
units.registry[unit] = formatter | ||
|
||
|
||
def _check_implicitly_registered(): | ||
global _WARN | ||
|
||
if _WARN: | ||
msg = ( | ||
"Using an implicitly registered datetime converter for a " | ||
"matplotlib plotting method. The converter was registered " | ||
"by pandas on import. Future versions of pandas will require " | ||
"you to explicitly register matplotlib converters.\n\n" | ||
"To register the converters:\n\t" | ||
">>> from pandas.plotting import register_matplotlib_converters" | ||
"\n\t" | ||
">>> register_matplotlib_converters()" | ||
) | ||
warnings.warn(msg, FutureWarning) | ||
_WARN = False | ||
|
||
|
||
def _to_ordinalf(tm): | ||
tot_sec = tm.hour * 3600 + tm.minute * 60 + tm.second + float(tm.microsecond / 1e6) | ||
return tot_sec | ||
|
@@ -253,7 +266,6 @@ class DatetimeConverter(dates.DateConverter): | |
@staticmethod | ||
def convert(values, unit, axis): | ||
# values might be a 1-d array, or a list-like of arrays. | ||
_check_implicitly_registered() | ||
if is_nested_list_like(values): | ||
values = [DatetimeConverter._convert_1d(v, unit, axis) for v in values] | ||
else: | ||
|
@@ -330,7 +342,6 @@ def __init__(self, locator, tz=None, defaultfmt="%Y-%m-%d"): | |
class PandasAutoDateLocator(dates.AutoDateLocator): | ||
def get_locator(self, dmin, dmax): | ||
"""Pick the best locator based on a distance.""" | ||
_check_implicitly_registered() | ||
delta = relativedelta(dmax, dmin) | ||
|
||
num_days = (delta.years * 12.0 + delta.months) * 31.0 + delta.days | ||
|
@@ -372,7 +383,6 @@ def get_unit_generic(freq): | |
|
||
def __call__(self): | ||
# if no data have been set, this will tank with a ValueError | ||
_check_implicitly_registered() | ||
try: | ||
dmin, dmax = self.viewlim_to_dt() | ||
except ValueError: | ||
|
@@ -990,7 +1000,6 @@ def _get_default_locs(self, vmin, vmax): | |
def __call__(self): | ||
"Return the locations of the ticks." | ||
# axis calls Locator.set_axis inside set_m<xxxx>_formatter | ||
_check_implicitly_registered() | ||
|
||
vi = tuple(self.axis.get_view_interval()) | ||
if vi != self.plot_obj.view_interval: | ||
|
@@ -1075,7 +1084,6 @@ def set_locs(self, locs): | |
"Sets the locations of the ticks" | ||
# don't actually use the locs. This is just needed to work with | ||
# matplotlib. Force to use vmin, vmax | ||
_check_implicitly_registered() | ||
|
||
self.locs = locs | ||
|
||
|
@@ -1088,7 +1096,6 @@ def set_locs(self, locs): | |
self._set_default_format(vmin, vmax) | ||
|
||
def __call__(self, x, pos=0): | ||
_check_implicitly_registered() | ||
|
||
if self.formatdict is None: | ||
return "" | ||
|
@@ -1120,7 +1127,6 @@ def format_timedelta_ticks(x, pos, n_decimals): | |
return s | ||
|
||
def __call__(self, x, pos=0): | ||
_check_implicitly_registered() | ||
(vmin, vmax) = tuple(self.axis.get_view_interval()) | ||
n_decimals = int(np.ceil(np.log10(100 * 1e9 / (vmax - vmin)))) | ||
if n_decimals > 9: | ||
|
Uh oh!
There was an error while loading. Please reload this page.