From ef7feb112565292322f9b780b17e82409b886c8a Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Mon, 20 Jul 2020 23:10:03 -0400 Subject: [PATCH 1/2] Merge pull request #17983 from jklymak/fix-pandas-need-num2epoch FIX: undeprecate and update num2epoch/epoch2num --- lib/matplotlib/dates.py | 38 ++++++++++++++---- lib/matplotlib/tests/test_dates.py | 63 ++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/dates.py b/lib/matplotlib/dates.py index 266c71fcc438..b92ea11daeef 100644 --- a/lib/matplotlib/dates.py +++ b/lib/matplotlib/dates.py @@ -1752,21 +1752,45 @@ def _get_interval(self): return self._interval -@cbook.deprecated("3.3") def epoch2num(e): """ - Convert an epoch or sequence of epochs to the new date format, - that is days since 0001. + Convert UNIX time to days since Matplotlib epoch. + + Parameters + ---------- + e : list of floats + Time in seconds since 1970-01-01. + + Returns + ------- + `numpy.array` + Time in days since Matplotlib epoch (see `~.dates.get_epoch()`). """ - return EPOCH_OFFSET + np.asarray(e) / SEC_PER_DAY + + dt = (np.datetime64('1970-01-01T00:00:00', 's') - + np.datetime64(get_epoch(), 's')).astype(float) + + return (dt + np.asarray(e)) / SEC_PER_DAY -@cbook.deprecated("3.3") def num2epoch(d): """ - Convert days since 0001 to epoch. *d* can be a number or sequence. + Convert days since Matplotlib epoch to UNIX time. + + Parameters + ---------- + d : list of floats + Time in days since Matplotlib epoch (see `~.dates.get_epoch()`). + + Returns + ------- + `numpy.array` + Time in seconds since 1970-01-01. """ - return (np.asarray(d) - EPOCH_OFFSET) * SEC_PER_DAY + dt = (np.datetime64('1970-01-01T00:00:00', 's') - + np.datetime64(get_epoch(), 's')).astype(float) + + return np.asarray(d) * SEC_PER_DAY - dt @cbook.deprecated("3.2") diff --git a/lib/matplotlib/tests/test_dates.py b/lib/matplotlib/tests/test_dates.py index b27b730c7919..26dc714000ba 100644 --- a/lib/matplotlib/tests/test_dates.py +++ b/lib/matplotlib/tests/test_dates.py @@ -947,3 +947,66 @@ 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() + + +def test_change_converter(): + plt.rcParams['date.converter'] = 'concise' + dates = np.arange('2020-01-01', '2020-05-01', dtype='datetime64[D]') + fig, ax = plt.subplots() + + ax.plot(dates, np.arange(len(dates))) + fig.canvas.draw() + assert ax.get_xticklabels()[0].get_text() == 'Jan' + assert ax.get_xticklabels()[1].get_text() == '15' + + plt.rcParams['date.converter'] = 'auto' + fig, ax = plt.subplots() + + ax.plot(dates, np.arange(len(dates))) + fig.canvas.draw() + assert ax.get_xticklabels()[0].get_text() == 'Jan 01 2020' + assert ax.get_xticklabels()[1].get_text() == 'Jan 15 2020' + with pytest.warns(UserWarning) as rec: + plt.rcParams['date.converter'] = 'boo' + + +def test_change_interval_multiples(): + plt.rcParams['date.interval_multiples'] = False + dates = np.arange('2020-01-10', '2020-05-01', dtype='datetime64[D]') + fig, ax = plt.subplots() + + ax.plot(dates, np.arange(len(dates))) + fig.canvas.draw() + assert ax.get_xticklabels()[0].get_text() == 'Jan 10 2020' + assert ax.get_xticklabels()[1].get_text() == 'Jan 24 2020' + + plt.rcParams['date.interval_multiples'] = 'True' + fig, ax = plt.subplots() + + ax.plot(dates, np.arange(len(dates))) + fig.canvas.draw() + assert ax.get_xticklabels()[0].get_text() == 'Jan 15 2020' + assert ax.get_xticklabels()[1].get_text() == 'Feb 01 2020' + + +def test_epoch2num(): + mdates._reset_epoch_test_example() + mdates.set_epoch('0000-12-31') + assert mdates.epoch2num(86400) == 719164.0 + assert mdates.num2epoch(719165.0) == 86400 * 2 + # set back to the default + mdates._reset_epoch_test_example() + mdates.set_epoch('1970-01-01T00:00:00') + assert mdates.epoch2num(86400) == 1.0 + assert mdates.num2epoch(2.0) == 86400 * 2 From b50fa140ca9005784a0a36b6ea2fc991d4587e34 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Mon, 20 Jul 2020 21:58:54 -0700 Subject: [PATCH 2/2] Backport PR #17983: FIX: undeprecate and update num2epoch/epoch2num --- doc/api/api_changes_3.4/deprecations.rst | 9 +++++ lib/matplotlib/tests/test_dates.py | 51 ------------------------ 2 files changed, 9 insertions(+), 51 deletions(-) diff --git a/doc/api/api_changes_3.4/deprecations.rst b/doc/api/api_changes_3.4/deprecations.rst index 097ecfda3a6e..79572183e01f 100644 --- a/doc/api/api_changes_3.4/deprecations.rst +++ b/doc/api/api_changes_3.4/deprecations.rst @@ -1,2 +1,11 @@ Deprecations ------------ + +Reverted deprecation of `~.dates.num2epoch` and `~.dates.epoch2num` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These two functions were deprecated in 3.3.0, and did not return +an accurate Matplotlib datenum relative to the new Matplotlib epoch +handling (`~.dates.get_epoch` and :rc:`date.epoch`). This version +reverts the deprecation and fixes those functions to work with +`~.dates.get_epoch`. diff --git a/lib/matplotlib/tests/test_dates.py b/lib/matplotlib/tests/test_dates.py index 26dc714000ba..68b337fe0093 100644 --- a/lib/matplotlib/tests/test_dates.py +++ b/lib/matplotlib/tests/test_dates.py @@ -949,57 +949,6 @@ def test_change_epoch(): 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() - - -def test_change_converter(): - plt.rcParams['date.converter'] = 'concise' - dates = np.arange('2020-01-01', '2020-05-01', dtype='datetime64[D]') - fig, ax = plt.subplots() - - ax.plot(dates, np.arange(len(dates))) - fig.canvas.draw() - assert ax.get_xticklabels()[0].get_text() == 'Jan' - assert ax.get_xticklabels()[1].get_text() == '15' - - plt.rcParams['date.converter'] = 'auto' - fig, ax = plt.subplots() - - ax.plot(dates, np.arange(len(dates))) - fig.canvas.draw() - assert ax.get_xticklabels()[0].get_text() == 'Jan 01 2020' - assert ax.get_xticklabels()[1].get_text() == 'Jan 15 2020' - with pytest.warns(UserWarning) as rec: - plt.rcParams['date.converter'] = 'boo' - - -def test_change_interval_multiples(): - plt.rcParams['date.interval_multiples'] = False - dates = np.arange('2020-01-10', '2020-05-01', dtype='datetime64[D]') - fig, ax = plt.subplots() - - ax.plot(dates, np.arange(len(dates))) - fig.canvas.draw() - assert ax.get_xticklabels()[0].get_text() == 'Jan 10 2020' - assert ax.get_xticklabels()[1].get_text() == 'Jan 24 2020' - - plt.rcParams['date.interval_multiples'] = 'True' - fig, ax = plt.subplots() - - ax.plot(dates, np.arange(len(dates))) - fig.canvas.draw() - assert ax.get_xticklabels()[0].get_text() == 'Jan 15 2020' - assert ax.get_xticklabels()[1].get_text() == 'Feb 01 2020' - - def test_epoch2num(): mdates._reset_epoch_test_example() mdates.set_epoch('0000-12-31')