From 4282445ed521eae2bd8775288df74899c8dc414d Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sat, 23 May 2020 11:27:42 +0100 Subject: [PATCH 01/23] adjust brackets in condition to rotate xticklabels --- doc/source/whatsnew/v1.1.0.rst | 1 + pandas/plotting/_matplotlib/core.py | 7 +++---- pandas/tests/plotting/test_frame.py | 10 ++++++++++ pandas/tests/plotting/test_series.py | 5 +++++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index a3499f857d158..0982877666f09 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -801,6 +801,7 @@ Plotting - Bug in :meth:`DataFrame.boxplot` and :meth:`DataFrame.plot.boxplot` lost color attributes of ``medianprops``, ``whiskerprops``, ``capprops`` and ``medianprops`` (:issue:`30346`) - Bug in :meth:`DataFrame.hist` where the order of ``column`` argument was ignored (:issue:`29235`) - Bug in :meth:`DataFrame.plot.scatter` that when adding multiple plots with different ``cmap``, colorbars alway use the first ``cmap`` (:issue:`33389`) +- Bug in :meth:`Dataframe.plot` was rotating xticklabels when subplots was equal to True, even if the values weren't dates (:issues:`29460`) Groupby/resample/rolling diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index a049ac99f0e08..052f5c1c88b86 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -1198,12 +1198,10 @@ def get_label(i): xticklabels = [get_label(x) for x in xticks] ax.set_xticklabels(xticklabels) ax.xaxis.set_major_locator(FixedLocator(xticks)) - condition = ( not self._use_dynamic_x() - and data.index.is_all_dates - and not self.subplots - or (self.subplots and self.sharex) + and (data.index.is_all_dates and self.use_index) + and (not self.subplots or (self.subplots and self.sharex)) ) index_name = self._get_index_name() @@ -1212,6 +1210,7 @@ def get_label(i): # irregular TS rotated 30 deg. by default # probably a better place to check / set this. if not self._rot_set: + # 1/0 self.rot = 30 format_date_labels(ax, rot=self.rot) diff --git a/pandas/tests/plotting/test_frame.py b/pandas/tests/plotting/test_frame.py index c84a09f21f46b..bf9dc288c9c1e 100644 --- a/pandas/tests/plotting/test_frame.py +++ b/pandas/tests/plotting/test_frame.py @@ -285,12 +285,14 @@ def test_xcompat(self): ax = df.plot(x_compat=True) lines = ax.get_lines() assert not isinstance(lines[0].get_xdata(), PeriodIndex) + self._check_ticks_props(ax, xrot=30) tm.close() pd.plotting.plot_params["xaxis.compat"] = True ax = df.plot() lines = ax.get_lines() assert not isinstance(lines[0].get_xdata(), PeriodIndex) + self._check_ticks_props(ax, xrot=0) tm.close() pd.plotting.plot_params["x_compat"] = False @@ -306,12 +308,14 @@ def test_xcompat(self): ax = df.plot() lines = ax.get_lines() assert not isinstance(lines[0].get_xdata(), PeriodIndex) + self._check_ticks_props(ax, xrot=30) tm.close() ax = df.plot() lines = ax.get_lines() assert not isinstance(lines[0].get_xdata(), PeriodIndex) assert isinstance(PeriodIndex(lines[0].get_xdata()), PeriodIndex) + self._check_ticks_props(ax, xrot=0) def test_period_compat(self): # GH 9012 @@ -3350,6 +3354,12 @@ def test_colors_of_columns_with_same_name(self): for legend, line in zip(result.get_legend().legendHandles, result.lines): assert legend.get_color() == line.get_color() + def test_subplots_non_date_axis(self): + # https://github.com/pandas-dev/pandas/issues/29460 + df = pd.DataFrame({"b": [0, 1, 0], "a": [1, 2, 3]}) + ax = _check_plot_works(df.plot, subplots=True) + self._check_ticks_props(ax, xrot=0) + def _generate_4_axes_via_gridspec(): import matplotlib.pyplot as plt diff --git a/pandas/tests/plotting/test_series.py b/pandas/tests/plotting/test_series.py index 5341878d4986e..178d6ca6a552a 100644 --- a/pandas/tests/plotting/test_series.py +++ b/pandas/tests/plotting/test_series.py @@ -109,6 +109,7 @@ def test_ts_area_lim(self): line = ax.get_lines()[0].get_data(orig=False)[0] assert xmin <= line[0] assert xmax >= line[-1] + self._check_ticks_props(ax, xrot=0) tm.close() # GH 7471 @@ -118,6 +119,7 @@ def test_ts_area_lim(self): line = ax.get_lines()[0].get_data(orig=False)[0] assert xmin <= line[0] assert xmax >= line[-1] + self._check_ticks_props(ax, xrot=30) tm.close() tz_ts = self.ts.copy() @@ -128,6 +130,7 @@ def test_ts_area_lim(self): line = ax.get_lines()[0].get_data(orig=False)[0] assert xmin <= line[0] assert xmax >= line[-1] + self._check_ticks_props(ax, xrot=0) tm.close() _, ax = self.plt.subplots() @@ -136,6 +139,7 @@ def test_ts_area_lim(self): line = ax.get_lines()[0].get_data(orig=False)[0] assert xmin <= line[0] assert xmax >= line[-1] + self._check_ticks_props(ax, xrot=0) def test_label(self): s = Series([1, 2]) @@ -282,6 +286,7 @@ def test_irregular_datetime(self): xp = datetime(1999, 1, 1).toordinal() ax.set_xlim("1/1/1999", "1/1/2001") assert xp == ax.get_xlim()[0] + self._check_ticks_props(ax, xrot=30) def test_unsorted_index_xlim(self): ser = Series( From 06e283f1d50d5af869e475a471db7d5a2190cc40 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sat, 23 May 2020 11:47:11 +0100 Subject: [PATCH 02/23] check rotation in use_index cases too --- pandas/tests/plotting/test_frame.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pandas/tests/plotting/test_frame.py b/pandas/tests/plotting/test_frame.py index bf9dc288c9c1e..6991f44ae7e42 100644 --- a/pandas/tests/plotting/test_frame.py +++ b/pandas/tests/plotting/test_frame.py @@ -65,6 +65,7 @@ def test_plot(self): with tm.assert_produces_warning(UserWarning): axes = _check_plot_works(df.plot, subplots=True, use_index=False) + self._check_ticks_props(axes, xrot=0) self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) df = DataFrame({"x": [1, 2], "y": [3, 4]}) @@ -77,7 +78,8 @@ def test_plot(self): df = DataFrame(np.random.rand(10, 3), index=list(string.ascii_letters[:10])) - _check_plot_works(df.plot, use_index=True) + ax = _check_plot_works(df.plot, use_index=True) + self._check_ticks_props(ax, xrot=0) _check_plot_works(df.plot, sort_columns=False) _check_plot_works(df.plot, yticks=[1, 5, 10]) _check_plot_works(df.plot, xticks=[1, 5, 10]) @@ -109,7 +111,8 @@ def test_plot(self): tuples = zip(string.ascii_letters[:10], range(10)) df = DataFrame(np.random.rand(10, 3), index=MultiIndex.from_tuples(tuples)) - _check_plot_works(df.plot, use_index=True) + ax = _check_plot_works(df.plot, use_index=True) + self._check_ticks_props(ax, xrot=0) # unicode index = MultiIndex.from_tuples( From 224962695a33bb6b279267f630b7f843611b8fb9 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sat, 23 May 2020 11:48:36 +0100 Subject: [PATCH 03/23] revert empty line --- pandas/plotting/_matplotlib/core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index 052f5c1c88b86..8ac9384ab6be2 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -1198,6 +1198,7 @@ def get_label(i): xticklabels = [get_label(x) for x in xticks] ax.set_xticklabels(xticklabels) ax.xaxis.set_major_locator(FixedLocator(xticks)) + condition = ( not self._use_dynamic_x() and (data.index.is_all_dates and self.use_index) From aa8bd31a3f9f3faafeb44ffb0f4099b4b5f33ac1 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sat, 23 May 2020 11:49:18 +0100 Subject: [PATCH 04/23] revert forced error --- pandas/plotting/_matplotlib/core.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index 8ac9384ab6be2..a4605fa4b3702 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -1211,7 +1211,6 @@ def get_label(i): # irregular TS rotated 30 deg. by default # probably a better place to check / set this. if not self._rot_set: - # 1/0 self.rot = 30 format_date_labels(ax, rot=self.rot) From cdb6ce28d7f1fdf0c8cc6e7fcec3cd7e3b674b98 Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Mon, 25 May 2020 13:01:46 +0100 Subject: [PATCH 05/23] Update v1.1.0.rst issues -> issue --- doc/source/whatsnew/v1.1.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 1009bb417157d..90e1967bba8c8 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -806,7 +806,7 @@ Plotting - Bug in :meth:`DataFrame.boxplot` and :meth:`DataFrame.plot.boxplot` lost color attributes of ``medianprops``, ``whiskerprops``, ``capprops`` and ``medianprops`` (:issue:`30346`) - Bug in :meth:`DataFrame.hist` where the order of ``column`` argument was ignored (:issue:`29235`) - Bug in :meth:`DataFrame.plot.scatter` that when adding multiple plots with different ``cmap``, colorbars alway use the first ``cmap`` (:issue:`33389`) -- Bug in :meth:`Dataframe.plot` was rotating xticklabels when subplots was equal to True, even if the values weren't dates (:issues:`29460`) +- Bug in :meth:`Dataframe.plot` was rotating xticklabels when subplots was equal to True, even if the values weren't dates (:issue:`29460`) Groupby/resample/rolling From ea9229247f79b87aea0d6297792814b68e8d1718 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sun, 14 Jun 2020 12:05:53 +0100 Subject: [PATCH 06/23] add comment --- pandas/plotting/_matplotlib/core.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index e13ef02729ce9..3940d7c2a3014 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -1202,6 +1202,11 @@ def get_label(i): ax.set_xticklabels(xticklabels) ax.xaxis.set_major_locator(FixedLocator(xticks)) + # If the index is an irregular time series, then by default + # we rotate the tick labels. The exception is if there are + # subplots which don't share their x-axes, in which we case + # we don't rotate the ticklabels as by default the subplots + # would be too close together. condition = ( not self._use_dynamic_x() and (data.index.is_all_dates and self.use_index) From 3fc993004fc752ae67d78d87eb3165a76c81a592 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sun, 14 Jun 2020 14:13:48 +0100 Subject: [PATCH 07/23] add tests which cover all the conditions --- pandas/tests/plotting/test_datetimelike.py | 32 +++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index 7dcb692e29337..b4b815a6431e0 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -8,7 +8,7 @@ import pandas.util._test_decorators as td -from pandas import DataFrame, Index, NaT, Series, isna +from pandas import DataFrame, Index, NaT, Series, isna, to_datetime import pandas._testing as tm from pandas.core.indexes.datetimes import bdate_range, date_range from pandas.core.indexes.period import Period, PeriodIndex, period_range @@ -1478,6 +1478,36 @@ def test_matplotlib_scatter_datetime64(self): expected = "2017-12-12" assert label.get_text() == expected + def test_check_xticks_rot(self): + # https://github.com/pandas-dev/pandas/issues/29460 + # irregular time series + df = DataFrame( + { + "x": to_datetime(["2020-05-01", "2020-05-02", "2020-05-04"]), + "y": [1, 2, 3], + } + ) + axes = df.plot(x="x", y="y") + self._check_ticks_props(axes, xrot=30) + + # use timeseries index + axes = df.set_index("x").plot(y="y", use_index=True) + self._check_ticks_props(axes, xrot=30) + + # use non-timeseries index + axes = df.plot(y="y", use_index=True) + self._check_ticks_props(axes, xrot=0) + + # dont sharex + axes = df.plot(x="x", y="y", sharex=False) + self._check_ticks_props(axes, xrot=0) + axes = df.plot(x="x", y="y", subplots=False, sharex=True) + self._check_ticks_props(axes, xrot=0) + + # sharex + axes = df.plot(x="x", y="y", sharex=True) + self._check_ticks_props(axes, xrot=30) + def _check_plot_works(f, freq=None, series=None, *args, **kwargs): import matplotlib.pyplot as plt From 85638c0871b0b585610ba810d71dfddf8876fc7f Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sun, 14 Jun 2020 14:41:52 +0100 Subject: [PATCH 08/23] wip --- pandas/plotting/_matplotlib/core.py | 2 +- pandas/tests/plotting/common.py | 2 +- pandas/tests/plotting/test_datetimelike.py | 35 ++++++++++++---------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index 3940d7c2a3014..55d0f30200325 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -1209,7 +1209,7 @@ def get_label(i): # would be too close together. condition = ( not self._use_dynamic_x() - and (data.index.is_all_dates and self.use_index) + and data.index.is_all_dates and (not self.subplots or (self.subplots and self.sharex)) ) diff --git a/pandas/tests/plotting/common.py b/pandas/tests/plotting/common.py index f2f7b37170ec9..628ce88d5c635 100644 --- a/pandas/tests/plotting/common.py +++ b/pandas/tests/plotting/common.py @@ -272,7 +272,7 @@ def _check_ticks_props( axes = self._flatten_visible(axes) for ax in axes: - if xlabelsize or xrot: + if xlabelsize or xrot is not None: if isinstance(ax.xaxis.get_minor_formatter(), NullFormatter): # If minor ticks has NullFormatter, rot / fontsize are not # retained diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index b4b815a6431e0..6bc2b4cf63db7 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -1481,6 +1481,7 @@ def test_matplotlib_scatter_datetime64(self): def test_check_xticks_rot(self): # https://github.com/pandas-dev/pandas/issues/29460 # irregular time series + fig, axes = self.plt.subplots() df = DataFrame( { "x": to_datetime(["2020-05-01", "2020-05-02", "2020-05-04"]), @@ -1488,25 +1489,29 @@ def test_check_xticks_rot(self): } ) axes = df.plot(x="x", y="y") - self._check_ticks_props(axes, xrot=30) + self._check_ticks_props(axes, xrot=0.0) - # use timeseries index - axes = df.set_index("x").plot(y="y", use_index=True) - self._check_ticks_props(axes, xrot=30) + # # use timeseries index + # df.set_index("x").plot(y="y", use_index=True, ax=axes) + # self._check_ticks_props(axes, xrot=0) - # use non-timeseries index - axes = df.plot(y="y", use_index=True) - self._check_ticks_props(axes, xrot=0) + # # use non-timeseries index + # axes = df.plot(y="y", use_index=True) + # self._check_ticks_props(axes, xrot=0) - # dont sharex - axes = df.plot(x="x", y="y", sharex=False) - self._check_ticks_props(axes, xrot=0) - axes = df.plot(x="x", y="y", subplots=False, sharex=True) - self._check_ticks_props(axes, xrot=0) + # # dont sharex + # axes = df.plot(x="x", y="y", sharex=False) + # self._check_ticks_props(axes, xrot=0) + # axes = df.plot(x="x", y="y", subplots=False, sharex=True) + # self._check_ticks_props(axes, xrot=0) - # sharex - axes = df.plot(x="x", y="y", sharex=True) - self._check_ticks_props(axes, xrot=30) + # # sharex + # axes = df.plot(x="x", y="y", sharex=True) + # self._check_ticks_props(axes, xrot=30) + + # # index of dates but don't use index + # axes = df.set_index('x').plot(y='y', use_index=False) + # self._check_ticks_props(axes, xrot=30) def _check_plot_works(f, freq=None, series=None, *args, **kwargs): From 7e01df8fecc15ba7e5090e69535d4be46a847be2 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Wed, 17 Jun 2020 19:55:15 +0100 Subject: [PATCH 09/23] remove xfails --- pandas/plotting/_matplotlib/core.py | 2 +- pandas/tests/plotting/test_datetimelike.py | 34 ++++++++++------------ pandas/tests/plotting/test_frame.py | 2 -- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index 46872ff6fd5a0..53585fc793d02 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -1213,7 +1213,7 @@ def get_label(i): # would be too close together. condition = ( not self._use_dynamic_x() - and data.index.is_all_dates + and (data.index.is_all_dates and self.use_index) and (not self.subplots or (self.subplots and self.sharex)) ) diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index 9693094d3a601..a7210d3710e54 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -1502,29 +1502,25 @@ def test_check_xticks_rot(self): } ) axes = df.plot(x="x", y="y") - self._check_ticks_props(axes, xrot=0.0) + self._check_ticks_props(axes, xrot=30) - # # use timeseries index - # df.set_index("x").plot(y="y", use_index=True, ax=axes) - # self._check_ticks_props(axes, xrot=0) + # use timeseries index + df.set_index("x").plot(y="y", use_index=True, ax=axes) + self._check_ticks_props(axes, xrot=30) - # # use non-timeseries index - # axes = df.plot(y="y", use_index=True) - # self._check_ticks_props(axes, xrot=0) + # use non-timeseries index + axes = df.plot(y="y", use_index=True) + self._check_ticks_props(axes, xrot=0) - # # dont sharex - # axes = df.plot(x="x", y="y", sharex=False) - # self._check_ticks_props(axes, xrot=0) - # axes = df.plot(x="x", y="y", subplots=False, sharex=True) - # self._check_ticks_props(axes, xrot=0) + # separate subplots + axes = df.plot(x="x", y="y", subplots=True, sharex=True) + self._check_ticks_props(axes, xrot=30) + axes = df.plot(x="x", y="y", subplots=True, sharex=False) + self._check_ticks_props(axes, xrot=0) - # # sharex - # axes = df.plot(x="x", y="y", sharex=True) - # self._check_ticks_props(axes, xrot=30) - - # # index of dates but don't use index - # axes = df.set_index('x').plot(y='y', use_index=False) - # self._check_ticks_props(axes, xrot=30) + # index of dates but don't use index + axes = df.set_index("x").plot(y="y", use_index=False) + self._check_ticks_props(axes, xrot=0) def _check_plot_works(f, freq=None, series=None, *args, **kwargs): diff --git a/pandas/tests/plotting/test_frame.py b/pandas/tests/plotting/test_frame.py index 8b5b7871b5892..24af353b50875 100644 --- a/pandas/tests/plotting/test_frame.py +++ b/pandas/tests/plotting/test_frame.py @@ -48,7 +48,6 @@ def _assert_xtickslabels_visibility(self, axes, expected): for ax, exp in zip(axes, expected): self._check_visible(ax.get_xticklabels(), visible=exp) - @pytest.mark.xfail(reason="Waiting for PR 34334", strict=True) @pytest.mark.slow def test_plot(self): from pandas.plotting._matplotlib.compat import _mpl_ge_3_1_0 @@ -475,7 +474,6 @@ def test_groupby_boxplot_sharex(self): expected = [False, False, True, True] self._assert_xtickslabels_visibility(axes, expected) - @pytest.mark.xfail(reason="Waiting for PR 34334", strict=True) @pytest.mark.slow def test_subplots_timeseries(self): idx = date_range(start="2014-07-01", freq="M", periods=10) From 2ea78de04b0c0f7dbff9b48e0807a99471588fe9 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Wed, 17 Jun 2020 19:57:24 +0100 Subject: [PATCH 10/23] check rot in existing test --- pandas/tests/plotting/test_frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/plotting/test_frame.py b/pandas/tests/plotting/test_frame.py index 24af353b50875..54946d9e5628f 100644 --- a/pandas/tests/plotting/test_frame.py +++ b/pandas/tests/plotting/test_frame.py @@ -295,7 +295,7 @@ def test_xcompat(self): ax = df.plot() lines = ax.get_lines() assert not isinstance(lines[0].get_xdata(), PeriodIndex) - self._check_ticks_props(ax, xrot=0) + self._check_ticks_props(ax, xrot=30) tm.close() pd.plotting.plot_params["x_compat"] = False From 23587168c21f2f9e8ce6486bbdf4dce3fdbef47b Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Wed, 17 Jun 2020 20:01:53 +0100 Subject: [PATCH 11/23] :art: --- pandas/tests/plotting/test_datetimelike.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index a7210d3710e54..ec2a137c104d5 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -1494,13 +1494,8 @@ def test_matplotlib_scatter_datetime64(self): def test_check_xticks_rot(self): # https://github.com/pandas-dev/pandas/issues/29460 # irregular time series - fig, axes = self.plt.subplots() - df = DataFrame( - { - "x": to_datetime(["2020-05-01", "2020-05-02", "2020-05-04"]), - "y": [1, 2, 3], - } - ) + x = to_datetime(["2020-05-01", "2020-05-02", "2020-05-04"]) + df = DataFrame({"x": x, "y": [1, 2, 3]}) axes = df.plot(x="x", y="y") self._check_ticks_props(axes, xrot=30) @@ -1508,10 +1503,6 @@ def test_check_xticks_rot(self): df.set_index("x").plot(y="y", use_index=True, ax=axes) self._check_ticks_props(axes, xrot=30) - # use non-timeseries index - axes = df.plot(y="y", use_index=True) - self._check_ticks_props(axes, xrot=0) - # separate subplots axes = df.plot(x="x", y="y", subplots=True, sharex=True) self._check_ticks_props(axes, xrot=30) From eacbe0a56cb72c41f4fa5956965f80d3a7293ed7 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Wed, 17 Jun 2020 20:03:15 +0100 Subject: [PATCH 12/23] add regular time series test --- pandas/tests/plotting/test_datetimelike.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index ec2a137c104d5..e4c3142b4556c 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -1513,6 +1513,12 @@ def test_check_xticks_rot(self): axes = df.set_index("x").plot(y="y", use_index=False) self._check_ticks_props(axes, xrot=0) + # regular time series + x = to_datetime(["2020-05-01", "2020-05-02", "2020-05-03"]) + df = DataFrame({"x": x, "y": [1, 2, 3]}) + axes = df.plot(x="x", y="y") + self._check_ticks_props(axes, xrot=0) + def _check_plot_works(f, freq=None, series=None, *args, **kwargs): import matplotlib.pyplot as plt From 836dd0d64fe580631bfaddc51047506c52dd58c0 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Thu, 18 Jun 2020 07:30:48 +0100 Subject: [PATCH 13/23] reword whatsnew --- doc/source/whatsnew/v1.1.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 7e389dc1d2f25..f65e7fbd1e847 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -997,7 +997,7 @@ Plotting - Bug in :meth:`DataFrame.boxplot` and :meth:`DataFrame.plot.boxplot` lost color attributes of ``medianprops``, ``whiskerprops``, ``capprops`` and ``medianprops`` (:issue:`30346`) - Bug in :meth:`DataFrame.hist` where the order of ``column`` argument was ignored (:issue:`29235`) - Bug in :meth:`DataFrame.plot.scatter` that when adding multiple plots with different ``cmap``, colorbars alway use the first ``cmap`` (:issue:`33389`) -- Bug in :meth:`Dataframe.plot` was rotating xticklabels when subplots was equal to True, even if the values weren't dates (:issue:`29460`) +- Bug in :meth:`Dataframe.plot` was rotating xticklabels when subplots was equal to True, even if the x-axis wasn't an irregular time series (:issue:`29460`) - Bug in :meth:`DataFrame.plot.scatter` was adding a colorbar to the plot even if the argument `c` was assigned to a column containing color names (:issue:`34316`) Groupby/resample/rolling From ea525ec4591c2736075be320173083112571fd34 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Thu, 18 Jun 2020 07:33:51 +0100 Subject: [PATCH 14/23] :art: --- pandas/tests/plotting/test_datetimelike.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index e4c3142b4556c..946c18840c8c8 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -1500,7 +1500,7 @@ def test_check_xticks_rot(self): self._check_ticks_props(axes, xrot=30) # use timeseries index - df.set_index("x").plot(y="y", use_index=True, ax=axes) + axes = df.set_index("x").plot(y="y", use_index=True) self._check_ticks_props(axes, xrot=30) # separate subplots From 85c4dc8ec06caf55af7a8b5bdfd047a96c755de9 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Thu, 18 Jun 2020 08:00:56 +0100 Subject: [PATCH 15/23] move _size_of_fmt to module level func --- pandas/io/formats/info.py | 41 ++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/pandas/io/formats/info.py b/pandas/io/formats/info.py index b1dcafa7a7a8f..0205bc258cbda 100644 --- a/pandas/io/formats/info.py +++ b/pandas/io/formats/info.py @@ -39,6 +39,37 @@ def _put_str(s: Union[str, Dtype], space: int) -> str: return str(s)[:space].ljust(space) +def _sizeof_fmt(num: Union[int, float], size_qualifier: str) -> str: + """ + Return size in human readable format. + + Parameters + ---------- + num : int + Size in bytes. + size_qualifier : str + Either empty, or '+' (if memory is lower bound). + + Returns + ------- + str + Size in human readable format. + + Examples + -------- + >>> _sizeof_fmt(23028, '') + '22.5 KB' + + >>> _sizeof_fmt(23028, '+') + '22.5+ KB' + """ + for x in ["bytes", "KB", "MB", "GB", "TB"]: + if num < 1024.0: + return f"{num:3.1f}{size_qualifier} {x}" + num /= 1024.0 + return f"{num:3.1f}{size_qualifier} PB" + + def _get_ids_and_dtypes(data: FrameOrSeries) -> Tuple["Index", "Series"]: """ Get DataFrame's columns and dtypes. @@ -119,7 +150,7 @@ def info( -------- %(examples_sub)s """ - if buf is None: # pragma: no cover + if buf is None: buf = sys.stdout lines = [] @@ -216,14 +247,6 @@ def _verbose_repr(): def _non_verbose_repr(): lines.append(ids._summary(name="Columns")) - def _sizeof_fmt(num, size_qualifier): - # returns size in human readable format - for x in ["bytes", "KB", "MB", "GB", "TB"]: - if num < 1024.0: - return f"{num:3.1f}{size_qualifier} {x}" - num /= 1024.0 - return f"{num:3.1f}{size_qualifier} PB" - if verbose: _verbose_repr() elif verbose is False: # specifically set to False, not necessarily None From 645905da0e7c80bdc7cebcab91f44da4a90a48e0 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Thu, 18 Jun 2020 15:08:19 +0100 Subject: [PATCH 16/23] regroup tests --- pandas/tests/plotting/test_datetimelike.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index 946c18840c8c8..1d25270cc38c4 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -1493,15 +1493,23 @@ def test_matplotlib_scatter_datetime64(self): def test_check_xticks_rot(self): # https://github.com/pandas-dev/pandas/issues/29460 + # regular time series + x = to_datetime(["2020-05-01", "2020-05-02", "2020-05-03"]) + df = DataFrame({"x": x, "y": [1, 2, 3]}) + axes = df.plot(x="x", y="y") + self._check_ticks_props(axes, xrot=0) + # irregular time series x = to_datetime(["2020-05-01", "2020-05-02", "2020-05-04"]) df = DataFrame({"x": x, "y": [1, 2, 3]}) axes = df.plot(x="x", y="y") self._check_ticks_props(axes, xrot=30) - # use timeseries index + # use timeseries index or not axes = df.set_index("x").plot(y="y", use_index=True) self._check_ticks_props(axes, xrot=30) + axes = df.set_index("x").plot(y="y", use_index=False) + self._check_ticks_props(axes, xrot=0) # separate subplots axes = df.plot(x="x", y="y", subplots=True, sharex=True) @@ -1509,16 +1517,6 @@ def test_check_xticks_rot(self): axes = df.plot(x="x", y="y", subplots=True, sharex=False) self._check_ticks_props(axes, xrot=0) - # index of dates but don't use index - axes = df.set_index("x").plot(y="y", use_index=False) - self._check_ticks_props(axes, xrot=0) - - # regular time series - x = to_datetime(["2020-05-01", "2020-05-02", "2020-05-03"]) - df = DataFrame({"x": x, "y": [1, 2, 3]}) - axes = df.plot(x="x", y="y") - self._check_ticks_props(axes, xrot=0) - def _check_plot_works(f, freq=None, series=None, *args, **kwargs): import matplotlib.pyplot as plt From c0c0e99ef6a62b95c5e2ae555abde645fbd052dc Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Thu, 18 Jun 2020 18:04:02 +0100 Subject: [PATCH 17/23] revert accidental change --- pandas/io/formats/info.py | 41 +++++++++------------------------------ 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/pandas/io/formats/info.py b/pandas/io/formats/info.py index 0205bc258cbda..b1dcafa7a7a8f 100644 --- a/pandas/io/formats/info.py +++ b/pandas/io/formats/info.py @@ -39,37 +39,6 @@ def _put_str(s: Union[str, Dtype], space: int) -> str: return str(s)[:space].ljust(space) -def _sizeof_fmt(num: Union[int, float], size_qualifier: str) -> str: - """ - Return size in human readable format. - - Parameters - ---------- - num : int - Size in bytes. - size_qualifier : str - Either empty, or '+' (if memory is lower bound). - - Returns - ------- - str - Size in human readable format. - - Examples - -------- - >>> _sizeof_fmt(23028, '') - '22.5 KB' - - >>> _sizeof_fmt(23028, '+') - '22.5+ KB' - """ - for x in ["bytes", "KB", "MB", "GB", "TB"]: - if num < 1024.0: - return f"{num:3.1f}{size_qualifier} {x}" - num /= 1024.0 - return f"{num:3.1f}{size_qualifier} PB" - - def _get_ids_and_dtypes(data: FrameOrSeries) -> Tuple["Index", "Series"]: """ Get DataFrame's columns and dtypes. @@ -150,7 +119,7 @@ def info( -------- %(examples_sub)s """ - if buf is None: + if buf is None: # pragma: no cover buf = sys.stdout lines = [] @@ -247,6 +216,14 @@ def _verbose_repr(): def _non_verbose_repr(): lines.append(ids._summary(name="Columns")) + def _sizeof_fmt(num, size_qualifier): + # returns size in human readable format + for x in ["bytes", "KB", "MB", "GB", "TB"]: + if num < 1024.0: + return f"{num:3.1f}{size_qualifier} {x}" + num /= 1024.0 + return f"{num:3.1f}{size_qualifier} PB" + if verbose: _verbose_repr() elif verbose is False: # specifically set to False, not necessarily None From bb5b080ad69ab6b89554c29c571d8ed0947a2b52 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Fri, 17 Jul 2020 14:19:09 +0100 Subject: [PATCH 18/23] typo --- doc/source/whatsnew/v1.1.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index b78879df5a72f..ee480d025087a 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -1099,7 +1099,7 @@ Plotting - Bug in :meth:`DataFrame.boxplot` and :meth:`DataFrame.plot.boxplot` lost color attributes of ``medianprops``, ``whiskerprops``, ``capprops`` and ``medianprops`` (:issue:`30346`) - Bug in :meth:`DataFrame.hist` where the order of ``column`` argument was ignored (:issue:`29235`) - Bug in :meth:`DataFrame.plot.scatter` that when adding multiple plots with different ``cmap``, colorbars alway use the first ``cmap`` (:issue:`33389`) -- Bug in :meth:`Dataframe.plot` was rotating xticklabels when subplots was equal to True, even if the x-axis wasn't an irregular time series (:issue:`29460`) +- Bug in :meth:`DataFrame.plot` was rotating xticklabels when subplots was equal to True, even if the x-axis wasn't an irregular time series (:issue:`29460`) - Bug in :meth:`DataFrame.plot.scatter` was adding a colorbar to the plot even if the argument `c` was assigned to a column containing color names (:issue:`34316`) - Bug in :meth:`pandas.plotting.bootstrap_plot` was causing cluttered axes and overlapping labels (:issue:`34905`) From 69a4c361c13798c0eaf5a7d6d1efe9299d5f7dc1 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Tue, 11 Aug 2020 19:55:24 +0100 Subject: [PATCH 19/23] doc --- doc/source/whatsnew/v1.2.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 86f47a5826214..968a4d166f9e2 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -239,7 +239,7 @@ I/O Plotting ^^^^^^^^ -- +- Bug in :meth:`DataFrame.plot` was rotating xticklabels when subplots was equal to True, even if the x-axis wasn't an irregular time series (:issue:`29460`) - Groupby/resample/rolling From b093d68f042b3d13f37560d0846c761d5c37ff2f Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Tue, 11 Aug 2020 19:56:16 +0100 Subject: [PATCH 20/23] remove unrealtde --- mybisect.sh | 2 -- pandas-dev.code-workspace | 7 ------- 2 files changed, 9 deletions(-) delete mode 100644 mybisect.sh delete mode 100644 pandas-dev.code-workspace diff --git a/mybisect.sh b/mybisect.sh deleted file mode 100644 index fd3bdb8891c38..0000000000000 --- a/mybisect.sh +++ /dev/null @@ -1,2 +0,0 @@ -python setup.py build_ext --inplace -j 8; -python pandas/tests/mytest.py diff --git a/pandas-dev.code-workspace b/pandas-dev.code-workspace deleted file mode 100644 index 362d7c25bb405..0000000000000 --- a/pandas-dev.code-workspace +++ /dev/null @@ -1,7 +0,0 @@ -{ - "folders": [ - { - "path": "." - } - ] -} \ No newline at end of file From 5746bd620f81d35010b104041e99b147429c67d3 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Tue, 11 Aug 2020 19:56:40 +0100 Subject: [PATCH 21/23] remove unrealtde --- pandas/tests/mytest.py | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 pandas/tests/mytest.py diff --git a/pandas/tests/mytest.py b/pandas/tests/mytest.py deleted file mode 100644 index 0a6439ba5cd59..0000000000000 --- a/pandas/tests/mytest.py +++ /dev/null @@ -1,14 +0,0 @@ -import pandas as pd - -df1 = pd.DataFrame( - { - "a": [3, 4, 5, 3, 5, 4, 1, 2, 3], - "b": [1, 3, 4, 5, 6, 5, 4, 4, 4], - "c": list("aabaaddce"), - "d": [3, 4, 5, 3, 5, 4, 1, 2, 3], - "e": [1, 3, 4, 5, 6, 5, 4, 4, 4], - "f": list("aabaaddce"), - } -) - -assert len(df1.groupby("b").agg(["cumsum"])) == len(df1) From 29de0292e172bda20d388b0aebb5c91954f8a5ae Mon Sep 17 00:00:00 2001 From: MarcoGorelli Date: Tue, 18 Aug 2020 19:42:56 +0100 Subject: [PATCH 22/23] make whatsnew more readable --- doc/source/whatsnew/v1.2.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 968a4d166f9e2..3aba5813ee172 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -239,7 +239,7 @@ I/O Plotting ^^^^^^^^ -- Bug in :meth:`DataFrame.plot` was rotating xticklabels when subplots was equal to True, even if the x-axis wasn't an irregular time series (:issue:`29460`) +- Bug in :meth:`DataFrame.plot` was rotating xticklabels when ``subplots=True``, even if the x-axis wasn't an irregular time series (:issue:`29460`) - Groupby/resample/rolling From 7ef0382d2e654852dcc629aab023e19a9f44fd64 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sun, 13 Sep 2020 20:07:22 +0100 Subject: [PATCH 23/23] :pencil2: --- doc/source/whatsnew/v1.2.0.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index f7f653dd2dad0..007b791d0a039 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -306,7 +306,6 @@ Plotting - Bug in :meth:`DataFrame.plot` was rotating xticklabels when ``subplots=True``, even if the x-axis wasn't an irregular time series (:issue:`29460`) - Bug in :meth:`DataFrame.plot` where a marker letter in the ``style`` keyword sometimes causes a ``ValueError`` (:issue:`21003`) -- Groupby/resample/rolling ^^^^^^^^^^^^^^^^^^^^^^^^