diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index fbca57206e163..6ff3f28440303 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -33,6 +33,8 @@ from pandas.plotting._matplotlib.style import _get_standard_colors from pandas.plotting._matplotlib.tools import ( _flatten, + _get_all_lines, + _get_xlim, _handle_shared_axes, _subplots, format_date_labels, @@ -1099,8 +1101,13 @@ def _make_plot(self): ) self._add_legend_handle(newlines[0], label, index=i) - # GH27686 set_xlim will truncate xaxis to fixed space - ax.relim() + if self._is_ts_plot(): + + # reset of xlim should be used for ts data + # TODO: GH28021, should find a way to change view limit on xaxis + lines = _get_all_lines(ax) + left, right = _get_xlim(lines) + ax.set_xlim(left, right) @classmethod def _plot(cls, ax, x, y, style=None, column_num=None, stacking_id=None, **kwds): diff --git a/pandas/plotting/_matplotlib/tools.py b/pandas/plotting/_matplotlib/tools.py index fd2913ca51ac3..67fa79ad5da8c 100644 --- a/pandas/plotting/_matplotlib/tools.py +++ b/pandas/plotting/_matplotlib/tools.py @@ -356,3 +356,24 @@ def _set_ticks_props(axes, xlabelsize=None, xrot=None, ylabelsize=None, yrot=Non if yrot is not None: plt.setp(ax.get_yticklabels(), rotation=yrot) return axes + + +def _get_all_lines(ax): + lines = ax.get_lines() + + if hasattr(ax, "right_ax"): + lines += ax.right_ax.get_lines() + + if hasattr(ax, "left_ax"): + lines += ax.left_ax.get_lines() + + return lines + + +def _get_xlim(lines): + left, right = np.inf, -np.inf + for l in lines: + x = l.get_xdata(orig=False) + left = min(np.nanmin(x), left) + right = max(np.nanmax(x), right) + return left, right diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index be87929b4545a..e2b7f2819f957 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -419,8 +419,6 @@ def test_get_finder(self): assert conv.get_finder("A") == conv._annual_finder assert conv.get_finder("W") == conv._daily_finder - # TODO: The finder should be retested due to wrong xlim values on x-axis - @pytest.mark.xfail(reason="TODO: check details in GH28021") @pytest.mark.slow def test_finder_daily(self): day_lst = [10, 40, 252, 400, 950, 2750, 10000] @@ -444,8 +442,6 @@ def test_finder_daily(self): assert rs1 == xpl1 assert rs2 == xpl2 - # TODO: The finder should be retested due to wrong xlim values on x-axis - @pytest.mark.xfail(reason="TODO: check details in GH28021") @pytest.mark.slow def test_finder_quarterly(self): yrs = [3.5, 11] @@ -469,8 +465,6 @@ def test_finder_quarterly(self): assert rs1 == xpl1 assert rs2 == xpl2 - # TODO: The finder should be retested due to wrong xlim values on x-axis - @pytest.mark.xfail(reason="TODO: check details in GH28021") @pytest.mark.slow def test_finder_monthly(self): yrs = [1.15, 2.5, 4, 11] @@ -504,8 +498,6 @@ def test_finder_monthly_long(self): xp = Period("1989Q1", "M").ordinal assert rs == xp - # TODO: The finder should be retested due to wrong xlim values on x-axis - @pytest.mark.xfail(reason="TODO: check details in GH28021") @pytest.mark.slow def test_finder_annual(self): xp = [1987, 1988, 1990, 1990, 1995, 2020, 2070, 2170] @@ -530,7 +522,7 @@ def test_finder_minutely(self): _, ax = self.plt.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() - rs = xaxis.get_majorticklocs()[1] + rs = xaxis.get_majorticklocs()[0] xp = Period("1/1/1999", freq="Min").ordinal assert rs == xp @@ -542,7 +534,7 @@ def test_finder_hourly(self): _, ax = self.plt.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() - rs = xaxis.get_majorticklocs()[1] + rs = xaxis.get_majorticklocs()[0] xp = Period("1/1/1999", freq="H").ordinal assert rs == xp @@ -1418,9 +1410,7 @@ def test_plot_outofbounds_datetime(self): def test_format_timedelta_ticks_narrow(self): - expected_labels = [ - "00:00:00.0000000{:0>2d}".format(i) for i in np.arange(0, 10, 2) - ] + expected_labels = ["00:00:00.0000000{:0>2d}".format(i) for i in np.arange(10)] rng = timedelta_range("0", periods=10, freq="ns") df = DataFrame(np.random.randn(len(rng), 3), rng) @@ -1430,8 +1420,8 @@ def test_format_timedelta_ticks_narrow(self): labels = ax.get_xticklabels() result_labels = [x.get_text() for x in labels] - assert (len(result_labels) - 2) == len(expected_labels) - assert result_labels[1:-1] == expected_labels + assert len(result_labels) == len(expected_labels) + assert result_labels == expected_labels def test_format_timedelta_ticks_wide(self): expected_labels = [ @@ -1454,8 +1444,8 @@ def test_format_timedelta_ticks_wide(self): labels = ax.get_xticklabels() result_labels = [x.get_text() for x in labels] - assert (len(result_labels) - 2) == len(expected_labels) - assert result_labels[1:-1] == expected_labels + assert len(result_labels) == len(expected_labels) + assert result_labels == expected_labels def test_timedelta_plot(self): # test issue #8711