From 8d4cee5019df3f05f3e2e10dfc26177527bd5b42 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 31 Mar 2019 23:09:38 -0400 Subject: [PATCH 1/7] FIX: restore de-confliction logic for minor ticks In #13363 when `iter_ticks` was deprecated the in-lined logic did not account for the updates from #13314. --- lib/matplotlib/axis.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 3569187e0fcf..5e9391f21271 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1064,17 +1064,18 @@ def _update_ticks(self): Update ticks (position and labels) using the current data interval of the axes. Return the list of ticks that will be drawn. """ - - major_locs = self.major.locator() - major_ticks = self.get_major_ticks(len(major_locs)) + major_locs = self.get_majorticklocs() major_labels = self.major.formatter.format_ticks(major_locs) + major_ticks = self.get_major_ticks(len(major_locs)) + self.major.formatter.set_locs(major_locs) for tick, loc, label in zip(major_ticks, major_locs, major_labels): tick.update_position(loc) tick.set_label1(label) tick.set_label2(label) - minor_locs = self.minor.locator() - minor_ticks = self.get_minor_ticks(len(minor_locs)) + minor_locs = self.get_minorticklocs() minor_labels = self.minor.formatter.format_ticks(minor_locs) + minor_ticks = self.get_minor_ticks(len(minor_locs)) + self.minor.formatter.set_locs(minor_locs) for tick, loc, label in zip(minor_ticks, minor_locs, minor_labels): tick.update_position(loc) tick.set_label1(label) From e3a83931ea42980a05e93741a44b1c7c6481da5f Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 8 Apr 2019 22:16:34 -0400 Subject: [PATCH 2/7] ENH: add flag to disable locator 'de-confliction' If Axis.remove_overlapping_locs is set to False the `Axis` object will not attempt to remove locations in the minor ticker that overlap with locations in the major ticker. This is a follow up to #13314 which un-conditionally removed the overlap. closes #13618 --- lib/matplotlib/axis.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 5e9391f21271..1cd860613c58 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -723,6 +723,8 @@ def __init__(self, axes, pickradius=15): `.Axis.contains`. """ martist.Artist.__init__(self) + self._remove_overlapping_locs = True + self.set_figure(axes.figure) self.isDefault_label = True @@ -754,6 +756,17 @@ def __init__(self, axes, pickradius=15): majorTicks = _LazyTickList(major=True) minorTicks = _LazyTickList(major=False) + def get_remove_overlapping_locs(self): + return self._remove_overlapping_locs + + def set_remove_overlapping_locs(self, val): + self._remove_overlapping_locs = bool(val) + + remove_overlapping_locs = property( + get_remove_overlapping_locs, set_remove_overlapping_locs, + doc=('If minor ticker locations that overlap with major ' + 'ticker locations should be trimmed.')) + def set_label_coords(self, x, y, transform=None): """ Set the coordinates of the label. @@ -1323,9 +1336,10 @@ def get_minorticklocs(self): # Use the transformed view limits as scale. 1e-5 is the default rtol # for np.isclose. tol = (hi - lo) * 1e-5 - minor_locs = [ - loc for loc, tr_loc in zip(minor_locs, tr_minor_locs) - if not np.isclose(tr_loc, tr_major_locs, atol=tol, rtol=0).any()] + if self.remove_overlapping_locs: + minor_locs = [ + loc for loc, tr_loc in zip(minor_locs, tr_minor_locs) + if ~np.isclose(tr_loc, tr_major_locs, atol=tol, rtol=0).any()] return minor_locs def get_ticklocs(self, minor=False): From 964e8cd74df9faca3694332684478ce0402a4686 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 8 Apr 2019 22:27:26 -0400 Subject: [PATCH 3/7] TST: add a test of not removing overlapping locations --- lib/matplotlib/tests/test_ticker.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py index b35a7fd45df8..1368e71f31f7 100644 --- a/lib/matplotlib/tests/test_ticker.py +++ b/lib/matplotlib/tests/test_ticker.py @@ -923,3 +923,24 @@ def minorticksubplot(xminor, yminor, i): minorticksubplot(True, False, 2) minorticksubplot(False, True, 3) minorticksubplot(True, True, 4) + + +def test_remove_overlap(): + import numpy as np + import matplotlib.dates as mdates + + t = np.arange("2018-11-03", "2018-11-06", dtype="datetime64") + x = np.ones(len(t)) + + fig, ax = plt.subplots() + ax.plot(t, x) + + ax.xaxis.set_major_locator(mdates.DayLocator()) + ax.xaxis.set_major_formatter(mdates.DateFormatter('\n%a')) + + ax.xaxis.set_minor_locator(mdates.HourLocator((0, 6, 12, 18))) + ax.xaxis.set_minor_formatter(mdates.DateFormatter('%H:%M')) + + assert len(ax.xaxis.get_minorticklocs()) == 6 + ax.xaxis.remove_overlapping_locs = False + assert len(ax.xaxis.get_minorticklocs()) == 9 From 24de3e90c960b1f4bfdf40ba30f8cc512f8cf255 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 10 Apr 2019 08:45:48 -0400 Subject: [PATCH 4/7] ENH: have `get_*_ticks` respect overlap filtering by default This will make sure extra ticks (that will not be used) will not be returned. The change to `get_major_ticks` is a no-op, but done for symmetry. --- lib/matplotlib/axis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 1cd860613c58..4aed0f242235 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1405,7 +1405,7 @@ def get_minor_formatter(self): def get_major_ticks(self, numticks=None): 'Get the tick instances; grow as necessary.' if numticks is None: - numticks = len(self.get_major_locator()()) + numticks = len(self.get_majorticklocs()) while len(self.majorTicks) < numticks: # Update the new tick label properties from the old. @@ -1419,7 +1419,7 @@ def get_major_ticks(self, numticks=None): def get_minor_ticks(self, numticks=None): 'Get the minor tick instances; grow as necessary.' if numticks is None: - numticks = len(self.get_minor_locator()()) + numticks = len(self.get_minorticklocs()) while len(self.minorTicks) < numticks: # Update the new tick label properties from the old. From e908efe37131da0697bd8e9c62444d37b4940ad3 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 10 Apr 2019 08:47:24 -0400 Subject: [PATCH 5/7] ENH: set non-used ticks to not visible This is to prevent user confusion if they are reaching directly into `Axis.minorTicks` and `Axis.majorTicks` and see ticks report they are visible but are not actually drawn. --- lib/matplotlib/axis.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 4aed0f242235..1855af151f27 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1095,6 +1095,11 @@ def _update_ticks(self): tick.set_label2(label) ticks = [*major_ticks, *minor_ticks] + # mark the ticks that we will not be using as not visible + for t in (self.minorTicks[len(minor_locs):] + + self.majorTicks[len(major_locs):]): + t.set_visible(False) + view_low, view_high = self.get_view_interval() if view_low > view_high: view_low, view_high = view_high, view_low From 0a6f575e9d82cba79557f123e939ff8301ae9fda Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 10 Apr 2019 08:56:58 -0400 Subject: [PATCH 6/7] TST: extend tests of remove_overlapping_locs --- lib/matplotlib/tests/test_ticker.py | 35 ++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py index 1368e71f31f7..8c52fc9dde9b 100644 --- a/lib/matplotlib/tests/test_ticker.py +++ b/lib/matplotlib/tests/test_ticker.py @@ -925,7 +925,11 @@ def minorticksubplot(xminor, yminor, i): minorticksubplot(True, True, 4) -def test_remove_overlap(): +@pytest.mark.parametrize('remove_overlapping_locs, expected_num', + ((True, 6), + (None, 6), # this tests the default + (False, 9))) +def test_remove_overlap(remove_overlapping_locs, expected_num): import numpy as np import matplotlib.dates as mdates @@ -940,7 +944,28 @@ def test_remove_overlap(): ax.xaxis.set_minor_locator(mdates.HourLocator((0, 6, 12, 18))) ax.xaxis.set_minor_formatter(mdates.DateFormatter('%H:%M')) - - assert len(ax.xaxis.get_minorticklocs()) == 6 - ax.xaxis.remove_overlapping_locs = False - assert len(ax.xaxis.get_minorticklocs()) == 9 + # force there to be extra ticks + ax.xaxis.get_minor_ticks(15) + if remove_overlapping_locs is not None: + ax.xaxis.remove_overlapping_locs = remove_overlapping_locs + + # check that getter/setter exists + current = ax.xaxis.remove_overlapping_locs + assert (current == ax.xaxis.get_remove_overlapping_locs()) + plt.setp(ax.xaxis, remove_overlapping_locs=current) + new = ax.xaxis.remove_overlapping_locs + assert (new == ax.xaxis.remove_overlapping_locs) + + # check that the accessors filter correctly + # this is the method that does the actual filtering + assert len(ax.xaxis.get_minorticklocs()) == expected_num + # these three are derivative + assert len(ax.xaxis.get_minor_ticks()) == expected_num + assert len(ax.xaxis.get_minorticklabels()) == expected_num + assert len(ax.xaxis.get_minorticklines()) == expected_num*2 + + # force a draw to call _update_ticks under the hood + fig.canvas.draw() + # check that the correct number of ticks report them selves as + # visible + assert sum(t.get_visible() for t in ax.xaxis.minorTicks) == expected_num From 00fbd77ba94ad9586183eafb4947500ee63b4100 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Thu, 11 Apr 2019 23:04:19 -0400 Subject: [PATCH 7/7] DOC: add remove_overlapping_locs to API page --- doc/api/axis_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/axis_api.rst b/doc/api/axis_api.rst index 3889b86498cb..8341d53448c1 100644 --- a/doc/api/axis_api.rst +++ b/doc/api/axis_api.rst @@ -60,7 +60,7 @@ Formatters and Locators Axis.set_major_locator Axis.set_minor_formatter Axis.set_minor_locator - + Axis.remove_overlapping_locs Axis Label ---------- pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy