Skip to content

Commit

Permalink
BUG: Enable plotting with PeriodIndex with arbitrary frequencies, res…
Browse files Browse the repository at this point in the history
…olves #14763 (#26241)

* BUG: Enable plotting with PeriodIndex with arbitrary frequencies, resolves #14763
  • Loading branch information
JoElfner authored and TomAugspurger committed May 28, 2019
1 parent 7f0a743 commit 7629a18
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 4 deletions.
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v0.25.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,8 @@ Plotting
- Fixed bug where :class:`api.extensions.ExtensionArray` could not be used in matplotlib plotting (:issue:`25587`)
- Bug in an error message in :meth:`DataFrame.plot`. Improved the error message if non-numerics are passed to :meth:`DataFrame.plot` (:issue:`25481`)
- Bug in incorrect ticklabel positions when plotting an index that are non-numeric / non-datetime (:issue:`7612` :issue:`15912` :issue:`22334`)
- Fixed bug causing plots of :class:`PeriodIndex` timeseries to fail if the frequency is a multiple of the frequency rule code (:issue:`14763`)
-
-
-

Expand Down
7 changes: 5 additions & 2 deletions pandas/plotting/_timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def _get_index_freq(data):
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):
if isinstance(data.index, (ABCDatetimeIndex, ABCPeriodIndex)):
freq = getattr(data.index, 'freq', None)

if freq is None:
Expand All @@ -279,7 +279,10 @@ def _maybe_convert_index(ax, data):
freq = get_base_alias(freq)
freq = frequencies.get_period_alias(freq)

data = data.to_period(freq=freq)
if isinstance(data.index, ABCDatetimeIndex):
data = data.to_period(freq=freq)
elif isinstance(data.index, ABCPeriodIndex):
data.index = data.index.asfreq(freq=freq)
return data


Expand Down
28 changes: 26 additions & 2 deletions pandas/tests/plotting/test_datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ class TestTSPlot(TestPlotBase):
def setup_method(self, method):
TestPlotBase.setup_method(self, method)

freq = ['S', 'T', 'H', 'D', 'W', 'M', 'Q', 'A']
idx = [period_range('12/31/1999', freq=x, periods=100) for x in freq]
self.freq = ['S', 'T', 'H', 'D', 'W', 'M', 'Q', 'A']
idx = [
period_range('12/31/1999', freq=x, periods=100) for x in self.freq]
self.period_ser = [Series(np.random.randn(len(x)), x) for x in idx]
self.period_df = [DataFrame(np.random.randn(len(x), 3), index=x,
columns=['A', 'B', 'C'])
Expand Down Expand Up @@ -209,6 +210,16 @@ def test_line_plot_period_series(self):
for s in self.period_ser:
_check_plot_works(s.plot, s.index.freq)

@pytest.mark.slow
@pytest.mark.parametrize(
'frqncy', ['1S', '3S', '5T', '7H', '4D', '8W', '11M', '3A'])
def test_line_plot_period_mlt_series(self, frqncy):
# test period index line plot for series with multiples (`mlt`) of the
# frequency (`frqncy`) rule code. tests resolution of issue #14763
idx = period_range('12/31/1999', freq=frqncy, periods=100)
s = Series(np.random.randn(len(idx)), idx)
_check_plot_works(s.plot, s.index.freq.rule_code)

@pytest.mark.slow
def test_line_plot_datetime_series(self):
for s in self.datetime_ser:
Expand All @@ -219,6 +230,19 @@ def test_line_plot_period_frame(self):
for df in self.period_df:
_check_plot_works(df.plot, df.index.freq)

@pytest.mark.slow
@pytest.mark.parametrize(
'frqncy', ['1S', '3S', '5T', '7H', '4D', '8W', '11M', '3A'])
def test_line_plot_period_mlt_frame(self, frqncy):
# test period index line plot for DataFrames with multiples (`mlt`)
# of the frequency (`frqncy`) rule code. tests resolution of issue
# #14763
idx = period_range('12/31/1999', freq=frqncy, periods=100)
df = DataFrame(np.random.randn(len(idx), 3), index=idx,
columns=['A', 'B', 'C'])
freq = df.index.asfreq(df.index.freq.rule_code).freq
_check_plot_works(df.plot, freq)

@pytest.mark.slow
def test_line_plot_datetime_frame(self):
for df in self.datetime_df:
Expand Down

0 comments on commit 7629a18

Please sign in to comment.