From 6560947991944b54cded39438b50ccfad3f9f19c Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Mon, 22 Jun 2020 21:20:31 -0700 Subject: [PATCH 1/3] FIX: properly handle dates when intmult is true --- lib/matplotlib/dates.py | 16 +++++------ lib/matplotlib/tests/test_dates.py | 43 +++++++++++++++++++----------- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/lib/matplotlib/dates.py b/lib/matplotlib/dates.py index 266c71fcc438..864c3c060c5d 100644 --- a/lib/matplotlib/dates.py +++ b/lib/matplotlib/dates.py @@ -1308,7 +1308,7 @@ def __init__(self, tz=None, minticks=5, maxticks=None, # Swap "3" for "4" in the DAILY list; If we use 3 we get bad # tick loc for months w/ 31 days: 1, 4, ..., 28, 31, 1 # If we use 4 then we get: 1, 5, ... 25, 29, 1 - self.intervald[DAILY] = [1, 2, 4, 7, 14, 21] + self.intervald[DAILY] = [1, 2, 4, 7, 14] self._byranges = [None, range(1, 13), range(1, 32), range(0, 24), range(0, 60), range(0, 60), None] @@ -1357,7 +1357,6 @@ def get_locator(self, dmin, dmax): if dmin > dmax: delta = -delta tdelta = -tdelta - # The following uses a mix of calls to relativedelta and timedelta # methods because there is incomplete overlap in the functionality of # these similar functions, and it's best to avoid doing our own math @@ -1400,13 +1399,12 @@ def get_locator(self, dmin, dmax): if num <= interval * (self.maxticks[freq] - 1): break else: - # We went through the whole loop without breaking, default to - # the last interval in the list and raise a warning - cbook._warn_external( - f"AutoDateLocator was unable to pick an appropriate " - f"interval for this date range. It may be necessary to " - f"add an interval value to the AutoDateLocator's " - f"intervald dictionary. Defaulting to {interval}.") + if not (self.interval_multiples and freq == DAILY): + cbook._warn_external( + f"AutoDateLocator was unable to pick an appropriate " + f"interval for this date range. It may be necessary " + f"to add an interval value to the AutoDateLocator's " + f"intervald dictionary. Defaulting to {interval}.") # Set some parameters as appropriate self._freq = freq diff --git a/lib/matplotlib/tests/test_dates.py b/lib/matplotlib/tests/test_dates.py index b27b730c7919..4d65a83024c0 100644 --- a/lib/matplotlib/tests/test_dates.py +++ b/lib/matplotlib/tests/test_dates.py @@ -398,11 +398,11 @@ def _create_auto_date_locator(date1, date2): '1997-11-01 00:00:00+00:00', '1997-12-01 00:00:00+00:00'] ], [datetime.timedelta(days=141), - ['1997-01-01 00:00:00+00:00', '1997-01-22 00:00:00+00:00', - '1997-02-01 00:00:00+00:00', '1997-02-22 00:00:00+00:00', - '1997-03-01 00:00:00+00:00', '1997-03-22 00:00:00+00:00', - '1997-04-01 00:00:00+00:00', '1997-04-22 00:00:00+00:00', - '1997-05-01 00:00:00+00:00', '1997-05-22 00:00:00+00:00'] + ['1997-01-01 00:00:00+00:00', '1997-01-15 00:00:00+00:00', + '1997-02-01 00:00:00+00:00', '1997-02-15 00:00:00+00:00', + '1997-03-01 00:00:00+00:00', '1997-03-15 00:00:00+00:00', + '1997-04-01 00:00:00+00:00', '1997-04-15 00:00:00+00:00', + '1997-05-01 00:00:00+00:00', '1997-05-15 00:00:00+00:00'] ], [datetime.timedelta(days=40), ['1997-01-01 00:00:00+00:00', '1997-01-05 00:00:00+00:00', @@ -471,8 +471,8 @@ def _create_auto_date_locator(date1, date2): 'Sep', 'Oct', 'Nov', 'Dec'] ], [datetime.timedelta(days=141), - ['Jan', '22', 'Feb', '22', 'Mar', '22', 'Apr', '22', - 'May', '22'] + ['Jan', '15', 'Feb', '15', 'Mar', '15', 'Apr', '15', + 'May', '15'] ], [datetime.timedelta(days=40), ['Jan', '05', '09', '13', '17', '21', '25', '29', 'Feb', @@ -523,8 +523,8 @@ def _create_auto_date_locator(date1, date2): '07/1997', '08/1997', '09/1997', '10/1997', '11/1997', '12/1997', ]], [datetime.timedelta(days=141), [ - '01/1997', 'day: 22', '02/1997', 'day: 22', '03/1997', 'day: 22', - '04/1997', 'day: 22', '05/1997', 'day: 22', + '01/1997', 'day: 15', '02/1997', 'day: 15', '03/1997', 'day: 15', + '04/1997', 'day: 15', '05/1997', 'day: 15', ]], [datetime.timedelta(days=40), [ '01/1997', 'day: 05', 'day: 09', 'day: 13', 'day: 17', 'day: 21', @@ -578,8 +578,8 @@ def _create_auto_date_locator(date1, date2): 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] ], [datetime.timedelta(days=141), - ['January', '22', 'February', '22', 'March', - '22', 'April', '22', 'May', '22'] + ['January', '15', 'February', '15', 'March', + '15', 'April', '15', 'May', '15'] ], [datetime.timedelta(days=40), ['January', '05', '09', '13', '17', '21', @@ -671,11 +671,11 @@ def _create_auto_date_locator(date1, date2, tz): '1997-11-01 00:00:00-08:00', '1997-12-01 00:00:00-08:00'] ], [datetime.timedelta(days=141), - ['1997-01-01 00:00:00-08:00', '1997-01-22 00:00:00-08:00', - '1997-02-01 00:00:00-08:00', '1997-02-22 00:00:00-08:00', - '1997-03-01 00:00:00-08:00', '1997-03-22 00:00:00-08:00', - '1997-04-01 00:00:00-08:00', '1997-04-22 00:00:00-07:00', - '1997-05-01 00:00:00-07:00', '1997-05-22 00:00:00-07:00'] + ['1997-01-01 00:00:00-08:00', '1997-01-15 00:00:00-08:00', + '1997-02-01 00:00:00-08:00', '1997-02-15 00:00:00-08:00', + '1997-03-01 00:00:00-08:00', '1997-03-15 00:00:00-08:00', + '1997-04-01 00:00:00-08:00', '1997-04-15 00:00:00-07:00', + '1997-05-01 00:00:00-07:00', '1997-05-15 00:00:00-07:00'] ], [datetime.timedelta(days=40), ['1997-01-01 00:00:00-08:00', '1997-01-05 00:00:00-08:00', @@ -947,3 +947,14 @@ def test_change_epoch(): np.testing.assert_allclose( mdates.date2num(np.datetime64('1970-01-01T12:00:00')), 0.5) + + +def test_warn_notintervals(): + dates = np.arange('2001-01-10', '2001-03-04', dtype='datetime64[D]') + locator = mdates.AutoDateLocator(interval_multiples=False) + locator.intervald[3] = [2] + locator.create_dummy_axis() + locator.set_view_interval(mdates.date2num(dates[0]), + mdates.date2num(dates[-1])) + with pytest.warns(UserWarning, match="AutoDateLocator was unable") as rec: + locs = locator() From da3644b550fa4d0b77207a76f61ca3961b685b77 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Mon, 29 Jun 2020 10:18:48 -0700 Subject: [PATCH 2/3] DOC: add API change note --- doc/api/next_api_changes/behavior/17727-JMK.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 doc/api/next_api_changes/behavior/17727-JMK.rst diff --git a/doc/api/next_api_changes/behavior/17727-JMK.rst b/doc/api/next_api_changes/behavior/17727-JMK.rst new file mode 100644 index 000000000000..ac82a7ab957b --- /dev/null +++ b/doc/api/next_api_changes/behavior/17727-JMK.rst @@ -0,0 +1,10 @@ + +Date locator for DAILY interval now returns middle of month +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The `.matplotlib.dates/AutoDateLocator` has a default of +`interval_multiples=True` that attempts to align ticks with the start of +meaningful intervals like the start of the month, or start of the day, etc. +That lead to approximately 140-day intervals being mapped to the first and 22nd +of the month. This has now been changed so that it chooses the first and +15th of the month, which is probably what most people want. From c8c9254e30195312d474985245e0c07d7c386245 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Fri, 3 Jul 2020 15:04:18 -0400 Subject: [PATCH 3/3] DOC: fix rst markup Co-authored-by: Elliott Sales de Andrade --- doc/api/next_api_changes/behavior/17727-JMK.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/next_api_changes/behavior/17727-JMK.rst b/doc/api/next_api_changes/behavior/17727-JMK.rst index ac82a7ab957b..cc6716f29184 100644 --- a/doc/api/next_api_changes/behavior/17727-JMK.rst +++ b/doc/api/next_api_changes/behavior/17727-JMK.rst @@ -2,8 +2,8 @@ Date locator for DAILY interval now returns middle of month ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The `.matplotlib.dates/AutoDateLocator` has a default of -`interval_multiples=True` that attempts to align ticks with the start of +The `matplotlib.dates.AutoDateLocator` has a default of +``interval_multiples=True`` that attempts to align ticks with the start of meaningful intervals like the start of the month, or start of the day, etc. That lead to approximately 140-day intervals being mapped to the first and 22nd of the month. This has now been changed so that it chooses the first and