BUG: mixed freq timeseries plotting with shared axes (GH13341) (#14330)

This commit is contained in:
Joris Van den Bossche 2016-11-26 10:13:05 +01:00 committed by GitHub
parent 75bb5308dd
commit 6d2b34af75
3 changed files with 64 additions and 9 deletions

View File

@ -39,7 +39,8 @@ Bug Fixes
- Bug in ``pd.cut`` with negative values and a single bin (:issue:`14652`)
- Bug in ``pd.to_numeric`` where a 0 was not unsigned on a ``downcast='unsigned'`` argument (:issue:`14401`)
- Bug in plotting regular and irregular timeseries using shared axes
(``sharex=True`` or ``ax.twinx()``) (:issue:`13341`, :issue:`14322`).

View File

@ -778,6 +778,41 @@ class TestTSPlot(TestPlotBase):
irreg.plot()
ps.plot()
def test_mixed_freq_shared_ax(self):
# GH13341, using sharex=True
idx1 = date_range('2015-01-01', periods=3, freq='M')
idx2 = idx1[:1].union(idx1[2:])
s1 = Series(range(len(idx1)), idx1)
s2 = Series(range(len(idx2)), idx2)
fig, (ax1, ax2) = self.plt.subplots(nrows=2, sharex=True)
s1.plot(ax=ax1)
s2.plot(ax=ax2)
self.assertEqual(ax1.freq, 'M')
self.assertEqual(ax2.freq, 'M')
self.assertEqual(ax1.lines[0].get_xydata()[0, 0],
ax2.lines[0].get_xydata()[0, 0])
# using twinx
fig, ax1 = self.plt.subplots()
ax2 = ax1.twinx()
s1.plot(ax=ax1)
s2.plot(ax=ax2)
self.assertEqual(ax1.lines[0].get_xydata()[0, 0],
ax2.lines[0].get_xydata()[0, 0])
# TODO (GH14330, GH14322)
# plotting the irregular first does not yet work
# fig, ax1 = plt.subplots()
# ax2 = ax1.twinx()
# s2.plot(ax=ax1)
# s1.plot(ax=ax2)
# self.assertEqual(ax1.lines[0].get_xydata()[0, 0],
# ax2.lines[0].get_xydata()[0, 0])
@slow
def test_to_weekly_resampling(self):
idxh = date_range('1/1/1999', periods=52, freq='W')

View File

@ -162,18 +162,37 @@ def _decorate_axes(ax, freq, kwargs):
ax.date_axis_info = None
def _get_ax_freq(ax):
"""
Get the freq attribute of the ax object if set.
Also checks shared axes (eg when using secondary yaxis, sharex=True
or twinx)
"""
ax_freq = getattr(ax, 'freq', None)
if ax_freq is None:
# check for left/right ax in case of secondary yaxis
if hasattr(ax, 'left_ax'):
ax_freq = getattr(ax.left_ax, 'freq', None)
elif hasattr(ax, 'right_ax'):
ax_freq = getattr(ax.right_ax, 'freq', None)
if ax_freq is None:
# check if a shared ax (sharex/twinx) has already freq set
shared_axes = ax.get_shared_x_axes().get_siblings(ax)
if len(shared_axes) > 1:
for shared_ax in shared_axes:
ax_freq = getattr(shared_ax, 'freq', None)
if ax_freq is not None:
break
return ax_freq
def _get_freq(ax, series):
# get frequency from data
freq = getattr(series.index, 'freq', None)
if freq is None:
freq = getattr(series.index, 'inferred_freq', None)
ax_freq = getattr(ax, 'freq', None)
if ax_freq is None:
if hasattr(ax, 'left_ax'):
ax_freq = getattr(ax.left_ax, 'freq', None)
elif hasattr(ax, 'right_ax'):
ax_freq = getattr(ax.right_ax, 'freq', None)
ax_freq = _get_ax_freq(ax)
# use axes freq if no data freq
if freq is None:
@ -191,7 +210,7 @@ def _get_freq(ax, series):
def _use_dynamic_x(ax, data):
freq = _get_index_freq(data)
ax_freq = getattr(ax, 'freq', None)
ax_freq = _get_ax_freq(ax)
if freq is None: # convert irregular if axes has freq info
freq = ax_freq
@ -244,7 +263,7 @@ def _maybe_convert_index(ax, data):
freq = freq.rule_code
if freq is None:
freq = getattr(ax, 'freq', None)
freq = _get_ax_freq(ax)
if freq is None:
raise ValueError('Could not get frequency alias for plotting')