From cabac51c695b9e61610dad77a90d6a27c528b9af Mon Sep 17 00:00:00 2001 From: Sujith Date: Sun, 18 Aug 2019 12:38:18 -0500 Subject: [PATCH 1/4] Hack Fix - Locators off by one day GH24784 When using any of the Locators the date calculation (x-axis labels) are off by one day in case of continuous dates. --- pandas/plotting/_matplotlib/timeseries.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pandas/plotting/_matplotlib/timeseries.py b/pandas/plotting/_matplotlib/timeseries.py index f3fcb090e9883..251912943102e 100644 --- a/pandas/plotting/_matplotlib/timeseries.py +++ b/pandas/plotting/_matplotlib/timeseries.py @@ -270,6 +270,12 @@ def _get_index_freq(data): weekdays = np.unique(data.index.dayofweek) if (5 in weekdays) or (6 in weekdays): freq = None + # This is a hack introduced to avoid tick resolution adjustment issue - Locators off by one day #24784 + elif freq == "D": + freq = None + elif freq.name == "D": + freq = None + # hack logic end - Locators off by one day #24784 return freq From 7f47cee9dcb7b2a362625bf80a85d099abf82133 Mon Sep 17 00:00:00 2001 From: Sujith Date: Sun, 18 Aug 2019 12:41:19 -0500 Subject: [PATCH 2/4] Hack Fix - test utility Introduced for GH24784 When using any of the Locators the date calculation (x-axis labels) are off by one day when continuous dates are provided. --- pandas/tests/plotting/common.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/pandas/tests/plotting/common.py b/pandas/tests/plotting/common.py index 5a591f72d7361..dae126350df6d 100644 --- a/pandas/tests/plotting/common.py +++ b/pandas/tests/plotting/common.py @@ -556,6 +556,35 @@ def _check_plot_works(f, filterwarnings="always", **kwargs): return ret +def _check_plot_works_with_continuous_dates(f, filterwarnings="always", **kwargs): + ''' first version of the test for - BUG 24784''' + import matplotlib.pyplot as plt + import matplotlib.dates as mdates + + ret = None + with warnings.catch_warnings(): + warnings.simplefilter(filterwarnings) + try: + try: + fig = kwargs["figure"] + except KeyError: + fig = plt.gcf() + + plt.clf() + + ax = kwargs.get("ax", fig.add_subplot(211)) # noqa + ret = f(**kwargs) + ret.xaxis.set_major_locator(mdates.DayLocator()) + ret.xaxis.set_major_formatter(mdates.DateFormatter("\n%b%d")) + + assert_is_valid_plot_return_object(ret) + + with ensure_clean(return_filelike=True) as path: + plt.savefig(path) + finally: + tm.close(fig) + + return ret def curpath(): pth, _ = os.path.split(os.path.abspath(__file__)) From 15f55d0ae37e5e2c2d9e561d4bcdf61fd11ff605 Mon Sep 17 00:00:00 2001 From: Sujith Date: Sun, 18 Aug 2019 12:44:06 -0500 Subject: [PATCH 3/4] Hack Fix - Test case submitted for GH24784 Locators off by one day When using any of the Locators the date calculation (x-axis labels) are off by one day when continuous dates are provided. --- pandas/tests/plotting/test_series.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/pandas/tests/plotting/test_series.py b/pandas/tests/plotting/test_series.py index 111c3a70fc09c..7ee0172b2c924 100644 --- a/pandas/tests/plotting/test_series.py +++ b/pandas/tests/plotting/test_series.py @@ -14,7 +14,7 @@ import pandas as pd from pandas import DataFrame, Series, date_range -from pandas.tests.plotting.common import TestPlotBase, _check_plot_works +from pandas.tests.plotting.common import TestPlotBase, _check_plot_works, _check_plot_works_with_continuous_dates import pandas.util.testing as tm import pandas.plotting as plotting @@ -731,6 +731,28 @@ def test_dup_datetime_index_plot(self): s = Series(values, index=index) _check_plot_works(s.plot) + @pytest.mark.slow + def test_continuous_dates(self): + s = Series(np.arange(10), name="x") + s_err = np.random.randn(10) + + ix = date_range("1/1/2018", "1/10/2018", freq="D") + ts = Series(np.arange(10), index=ix, name="x") + ts_err = Series(np.random.randn(10), index=ix) + td_err = DataFrame(randn(10, 2), index=ix, columns=["x", "y"]) + ax = _check_plot_works_with_continuous_dates(ts.plot, yerr=ts_err) + + self._check_text_labels(ax.get_xticklabels(), ["\nJan01", "\nJan02", "\nJan03", "\nJan04", "\nJan05", + "\nJan06", "\nJan07", "\nJan08", "\nJan09", "\nJan10"]) + + # check incorrect lengths and types + with pytest.raises(ValueError): + s.plot(yerr=np.arange(11)) + + s_err = ["zzz"] * 10 + with pytest.raises(TypeError): + s.plot(yerr=s_err) + @pytest.mark.slow def test_errorbar_plot(self): From ae6bf34cb2e4b4d82990e51840d6b5f5c472e5c4 Mon Sep 17 00:00:00 2001 From: Sujith Date: Sun, 18 Aug 2019 13:52:35 -0500 Subject: [PATCH 4/4] Update timeseries.py --- pandas/plotting/_matplotlib/timeseries.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/plotting/_matplotlib/timeseries.py b/pandas/plotting/_matplotlib/timeseries.py index 251912943102e..a5ff25825009c 100644 --- a/pandas/plotting/_matplotlib/timeseries.py +++ b/pandas/plotting/_matplotlib/timeseries.py @@ -270,7 +270,8 @@ def _get_index_freq(data): weekdays = np.unique(data.index.dayofweek) if (5 in weekdays) or (6 in weekdays): freq = None - # This is a hack introduced to avoid tick resolution adjustment issue - Locators off by one day #24784 + # This is a hack introduced to avoid tick resolution adjustment issue - + # Locators off by one day #24784 elif freq == "D": freq = None elif freq.name == "D":