Skip to content

TYP: annotations in plotting code #34469

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 2 commits into from
May 31, 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
10 changes: 5 additions & 5 deletions pandas/plotting/_matplotlib/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def deregister():
units.registry[unit] = formatter


def _to_ordinalf(tm):
def _to_ordinalf(tm: pydt.time) -> float:
tot_sec = tm.hour * 3600 + tm.minute * 60 + tm.second + float(tm.microsecond / 1e6)
return tot_sec

Expand Down Expand Up @@ -160,7 +160,7 @@ class TimeFormatter(Formatter):
def __init__(self, locs):
self.locs = locs

def __call__(self, x, pos=0):
def __call__(self, x, pos=0) -> str:
"""
Return the time of day as a formatted string.

Expand Down Expand Up @@ -1049,7 +1049,7 @@ def set_locs(self, locs):
(vmin, vmax) = (vmax, vmin)
self._set_default_format(vmin, vmax)

def __call__(self, x, pos=0):
def __call__(self, x, pos=0) -> str:

if self.formatdict is None:
return ""
Expand All @@ -1066,7 +1066,7 @@ class TimeSeries_TimedeltaFormatter(Formatter):
"""

@staticmethod
def format_timedelta_ticks(x, pos, n_decimals):
def format_timedelta_ticks(x, pos, n_decimals: int) -> str:
"""
Convert seconds to 'D days HH:MM:SS.F'
"""
Expand All @@ -1082,7 +1082,7 @@ def format_timedelta_ticks(x, pos, n_decimals):
s = f"{int(d):d} days {s}"
return s

def __call__(self, x, pos=0):
def __call__(self, x, pos=0) -> str:
(vmin, vmax) = tuple(self.axis.get_view_interval())
n_decimals = int(np.ceil(np.log10(100 * 1e9 / (vmax - vmin))))
if n_decimals > 9:
Expand Down
49 changes: 31 additions & 18 deletions pandas/plotting/_matplotlib/timeseries.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# TODO: Use the fact that axis can have units to simplify the process

import functools
from typing import Optional
from typing import TYPE_CHECKING, Optional

import numpy as np

Expand All @@ -20,15 +20,23 @@
TimeSeries_DateLocator,
TimeSeries_TimedeltaFormatter,
)
import pandas.tseries.frequencies as frequencies
from pandas.tseries.frequencies import is_subperiod, is_superperiod
from pandas.tseries.frequencies import (
get_period_alias,
is_subperiod,
is_superperiod,
to_offset,
)
from pandas.tseries.offsets import DateOffset

if TYPE_CHECKING:
from pandas import Series, Index # noqa:F401


# ---------------------------------------------------------------------
# Plotting functions and monkey patches


def _maybe_resample(series, ax, kwargs):
def _maybe_resample(series: "Series", ax, kwargs):
# resample against axes freq if necessary
freq, ax_freq = _get_freq(ax, series)

Expand All @@ -42,7 +50,7 @@ def _maybe_resample(series, ax, kwargs):
if ax_freq is not None and freq != ax_freq:
if is_superperiod(freq, ax_freq): # upsample input
series = series.copy()
series.index = series.index.asfreq(ax_freq, how="s")
series.index = series.index.asfreq(ax_freq, how="s") # type: ignore
freq = ax_freq
elif _is_sup(freq, ax_freq): # one is weekly
how = kwargs.pop("how", "last")
Expand Down Expand Up @@ -161,21 +169,22 @@ def _get_ax_freq(ax):
return ax_freq


def get_period_alias(freq) -> Optional[str]:
def _get_period_alias(freq) -> Optional[str]:
if isinstance(freq, DateOffset):
freq = freq.rule_code
else:
freq = base_and_stride(freq)[0]

freq = frequencies.get_period_alias(freq)
freq = get_period_alias(freq)
return freq


def _get_freq(ax, series):
def _get_freq(ax, series: "Series"):
# get frequency from data
freq = getattr(series.index, "freq", None)
if freq is None:
freq = getattr(series.index, "inferred_freq", None)
freq = to_offset(freq)

ax_freq = _get_ax_freq(ax)

Expand All @@ -184,12 +193,12 @@ def _get_freq(ax, series):
freq = ax_freq

# get the period frequency
freq = get_period_alias(freq)
freq = _get_period_alias(freq)
return freq, ax_freq


def _use_dynamic_x(ax, data):
freq = _get_index_freq(data)
freq = _get_index_freq(data.index)
ax_freq = _get_ax_freq(ax)

if freq is None: # convert irregular if axes has freq info
Expand All @@ -201,7 +210,7 @@ def _use_dynamic_x(ax, data):
if freq is None:
return False

freq = get_period_alias(freq)
freq = _get_period_alias(freq)

if freq is None:
return False
Expand All @@ -216,33 +225,37 @@ def _use_dynamic_x(ax, data):
return True


def _get_index_freq(data):
freq = getattr(data.index, "freq", None)
def _get_index_freq(index: "Index") -> Optional[DateOffset]:
freq = getattr(index, "freq", None)
if freq is None:
freq = getattr(data.index, "inferred_freq", None)
freq = getattr(index, "inferred_freq", None)
if freq == "B":
weekdays = np.unique(data.index.dayofweek)
weekdays = np.unique(index.dayofweek) # type: ignore
if (5 in weekdays) or (6 in weekdays):
freq = None

freq = to_offset(freq)
return freq


def _maybe_convert_index(ax, data):
# tsplot converts automatically, but don't want to convert index
# over and over for DataFrames
if isinstance(data.index, (ABCDatetimeIndex, ABCPeriodIndex)):
freq = getattr(data.index, "freq", None)
freq = data.index.freq

if freq is None:
freq = getattr(data.index, "inferred_freq", None)
# We only get here for DatetimeIndex
freq = data.index.inferred_freq
freq = to_offset(freq)

if freq is None:
freq = _get_ax_freq(ax)

if freq is None:
raise ValueError("Could not get frequency alias for plotting")

freq = get_period_alias(freq)
freq = _get_period_alias(freq)

if isinstance(data.index, ABCDatetimeIndex):
data = data.tz_localize(None).to_period(freq=freq)
Expand Down