Skip to content

REF: ensure we have offset objects in plotting functions #34585

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

Merged
merged 1 commit into from
Jun 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 26 additions & 25 deletions pandas/plotting/_matplotlib/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import numpy as np

from pandas._libs import lib, tslibs
from pandas._libs.tslibs.frequencies import FreqGroup, get_freq_code, get_freq_group
from pandas._libs.tslibs import to_offset
from pandas._libs.tslibs.frequencies import FreqGroup, get_freq_group
from pandas._libs.tslibs.offsets import BaseOffset

from pandas.core.dtypes.common import (
is_datetime64_ns_dtype,
Expand Down Expand Up @@ -522,34 +524,36 @@ def has_level_label(label_flags, vmin):
return True


def _daily_finder(vmin, vmax, freq):
def _daily_finder(vmin, vmax, freq: BaseOffset):
dtype_code = freq._period_dtype_code

periodsperday = -1

if freq >= FreqGroup.FR_HR:
if freq == FreqGroup.FR_NS:
if dtype_code >= FreqGroup.FR_HR:
if dtype_code == FreqGroup.FR_NS:
periodsperday = 24 * 60 * 60 * 1000000000
elif freq == FreqGroup.FR_US:
elif dtype_code == FreqGroup.FR_US:
periodsperday = 24 * 60 * 60 * 1000000
elif freq == FreqGroup.FR_MS:
elif dtype_code == FreqGroup.FR_MS:
periodsperday = 24 * 60 * 60 * 1000
elif freq == FreqGroup.FR_SEC:
elif dtype_code == FreqGroup.FR_SEC:
periodsperday = 24 * 60 * 60
elif freq == FreqGroup.FR_MIN:
elif dtype_code == FreqGroup.FR_MIN:
periodsperday = 24 * 60
elif freq == FreqGroup.FR_HR:
elif dtype_code == FreqGroup.FR_HR:
periodsperday = 24
else: # pragma: no cover
raise ValueError(f"unexpected frequency: {freq}")
raise ValueError(f"unexpected frequency: {dtype_code}")
periodsperyear = 365 * periodsperday
periodspermonth = 28 * periodsperday

elif freq == FreqGroup.FR_BUS:
elif dtype_code == FreqGroup.FR_BUS:
periodsperyear = 261
periodspermonth = 19
elif freq == FreqGroup.FR_DAY:
elif dtype_code == FreqGroup.FR_DAY:
periodsperyear = 365
periodspermonth = 28
elif get_freq_group(freq) == FreqGroup.FR_WK:
elif get_freq_group(dtype_code) == FreqGroup.FR_WK:
periodsperyear = 52
periodspermonth = 3
else: # pragma: no cover
Expand Down Expand Up @@ -676,7 +680,7 @@ def _second_finder(label_interval):
elif span <= periodsperyear // 4:
month_start = period_break(dates_, "month")
info_maj[month_start] = True
if freq < FreqGroup.FR_HR:
if dtype_code < FreqGroup.FR_HR:
info["min"] = True
else:
day_start = period_break(dates_, "day")
Expand Down Expand Up @@ -884,21 +888,20 @@ def _annual_finder(vmin, vmax, freq):
return info


def get_finder(freq):
if isinstance(freq, str):
freq = get_freq_code(freq)[0]
fgroup = get_freq_group(freq)
def get_finder(freq: BaseOffset):
dtype_code = freq._period_dtype_code
fgroup = (dtype_code // 1000) * 1000

if fgroup == FreqGroup.FR_ANN:
return _annual_finder
elif fgroup == FreqGroup.FR_QTR:
return _quarterly_finder
elif freq == FreqGroup.FR_MTH:
elif dtype_code == FreqGroup.FR_MTH:
return _monthly_finder
elif (freq >= FreqGroup.FR_BUS) or fgroup == FreqGroup.FR_WK:
elif (dtype_code >= FreqGroup.FR_BUS) or fgroup == FreqGroup.FR_WK:
return _daily_finder
else: # pragma: no cover
raise NotImplementedError(f"Unsupported frequency: {freq}")
raise NotImplementedError(f"Unsupported frequency: {dtype_code}")


class TimeSeries_DateLocator(Locator):
Expand Down Expand Up @@ -930,8 +933,7 @@ def __init__(
day=1,
plot_obj=None,
):
if isinstance(freq, str):
freq = get_freq_code(freq)[0]
freq = to_offset(freq)
self.freq = freq
self.base = base
(self.quarter, self.month, self.day) = (quarter, month, day)
Expand Down Expand Up @@ -1009,8 +1011,7 @@ class TimeSeries_DateFormatter(Formatter):
"""

def __init__(self, freq, minor_locator=False, dynamic_mode=True, plot_obj=None):
if isinstance(freq, str):
freq = get_freq_code(freq)[0]
freq = to_offset(freq)
self.format = None
self.freq = freq
self.locs = []
Expand Down
13 changes: 7 additions & 6 deletions pandas/tests/plotting/test_datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import numpy as np
import pytest

from pandas._libs.tslibs import to_offset
import pandas.util._test_decorators as td

from pandas import DataFrame, Index, NaT, Series, isna
Expand Down Expand Up @@ -397,12 +398,12 @@ def _test(ax):
def test_get_finder(self):
import pandas.plotting._matplotlib.converter as conv

assert conv.get_finder("B") == conv._daily_finder
assert conv.get_finder("D") == conv._daily_finder
assert conv.get_finder("M") == conv._monthly_finder
assert conv.get_finder("Q") == conv._quarterly_finder
assert conv.get_finder("A") == conv._annual_finder
assert conv.get_finder("W") == conv._daily_finder
assert conv.get_finder(to_offset("B")) == conv._daily_finder
assert conv.get_finder(to_offset("D")) == conv._daily_finder
assert conv.get_finder(to_offset("M")) == conv._monthly_finder
assert conv.get_finder(to_offset("Q")) == conv._quarterly_finder
assert conv.get_finder(to_offset("A")) == conv._annual_finder
assert conv.get_finder(to_offset("W")) == conv._daily_finder

@pytest.mark.slow
def test_finder_daily(self):
Expand Down