BUG: mixed freq timeseries plotting with shared axes (GH13341) (#14330)
This commit is contained in:
parent
75bb5308dd
commit
6d2b34af75
|
@ -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`).
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in New Issue