diff --git a/doc/api/artist_api.rst b/doc/api/artist_api.rst index 3903bbd5924d..4f3d8a8a7bcc 100644 --- a/doc/api/artist_api.rst +++ b/doc/api/artist_api.rst @@ -182,6 +182,8 @@ Miscellaneous :nosignatures: Artist.sticky_edges + Artist.set_in_autoscale + Artist.get_in_autoscale Artist.set_in_layout Artist.get_in_layout Artist.stale diff --git a/doc/users/next_whats_new/2019-11-02-in_autoscale.rst b/doc/users/next_whats_new/2019-11-02-in_autoscale.rst new file mode 100644 index 000000000000..85d0639cbdab --- /dev/null +++ b/doc/users/next_whats_new/2019-11-02-in_autoscale.rst @@ -0,0 +1,5 @@ +``Artist`` gained an ``set_in_autoscale()`` method +--------------------------------------------------- + +The ``Artist`` class gained an ``set_in_autoscale()`` method which +is used to determine if the instance is used in the autoscale calculation. diff --git a/lib/matplotlib/artist.py b/lib/matplotlib/artist.py index d03c8b6d75fc..937d96a4d27f 100644 --- a/lib/matplotlib/artist.py +++ b/lib/matplotlib/artist.py @@ -212,6 +212,7 @@ def __init__(self): self._path_effects = mpl.rcParams['path.effects'] self._sticky_edges = _XYPair([], []) self._in_layout = True + self._in_autoscale = True def __getstate__(self): d = self.__dict__.copy() @@ -887,6 +888,13 @@ def _fully_clipped_to_axes(self): or isinstance(clip_path, TransformedPatchPath) and clip_path._patch is self.axes.patch)) + def get_in_autoscale(self): + """ + Return boolean flag, ``True`` if artist is included in autoscale + calculations. + """ + return self._in_autoscale + def get_clip_on(self): """Return whether the artist uses clipping.""" return self._clipon @@ -1090,6 +1098,16 @@ def set_in_layout(self, in_layout): """ self._in_layout = in_layout + def set_in_autoscale(self, in_autoscale): + """ + Set if artist is to be included in autoscale calculations. + + Parameters + ---------- + in_autoscale : bool + """ + self._in_autoscale = in_autoscale + def get_label(self): """Return the label used for this artist in the legend.""" return self._label diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 8a105f4da67d..ebac90bc0584 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -2289,6 +2289,8 @@ def add_image(self, image): return image def _update_image_limits(self, image): + if not image.get_in_autoscale(): + return xmin, xmax, ymin, ymax = image.get_extent() self.axes.update_datalim(((xmin, ymin), (xmax, ymax))) @@ -2324,6 +2326,9 @@ def _update_line_limits(self, line): """ Figures out the data limit of the given line, updating self.dataLim. """ + if not line.get_in_autoscale(): + return + path = line.get_path() if path.vertices.size == 0: return @@ -2391,6 +2396,9 @@ def _update_patch_limits(self, patch): # cannot check for '==0' since unitized data may not compare to zero # issue #2150 - we update the limits if patch has non zero width # or height. + if not patch.get_in_autoscale(): + return + if (isinstance(patch, mpatches.Rectangle) and ((not patch.get_width()) and (not patch.get_height()))): return diff --git a/lib/matplotlib/tests/test_artist.py b/lib/matplotlib/tests/test_artist.py index 9bfb4ebce1bd..cf217698fbb3 100644 --- a/lib/matplotlib/tests/test_artist.py +++ b/lib/matplotlib/tests/test_artist.py @@ -562,3 +562,45 @@ def draw(self, renderer, extra): assert 'aardvark' == art.draw(renderer, 'aardvark') assert 'aardvark' == art.draw(renderer, extra='aardvark') + + +def test_line_in_autoscale_true(): + # test autoscale is performed when in_autoscale=True for a line. + fig, ax = plt.subplots() + ax.plot([0, 1]) + ax.plot([0, 1, 2, 3], in_autoscale=True) + ax.margins(0) + ax.autoscale_view() + assert ax.get_xlim() == ax.get_ylim() == (0, 3) + + +def test_line_in_autoscale_false(): + # test autoscale is not performed when in_autoscale=False for a line. + fig, ax = plt.subplots() + ax.plot([0, 1]) + ax.plot([0, 1, 2, 3], in_autoscale=False) + ax.margins(0) + ax.autoscale_view() + assert ax.get_xlim() == ax.get_ylim() == (0, 1) # The default limits. + + +def test_patch_in_autoscale_true(): + # test autoscale is performed when in_autoscale=True for a patch. + fig, ax = plt.subplots() + ax.plot([0, 1]) + ax.bar([0, 1, 2, 3], [0, 10, 20, 30], width=0.5, in_autoscale=True) + ax.margins(0) + ax.autoscale_view() + assert ax.get_xlim() == (-.25, 3.25) + assert ax.get_ylim() == (0, 30) + + +def test_patch_in_autoscale_false(): + # test autoscale is not performed when in_autoscale=False for a patch. + fig, ax = plt.subplots() + ax.plot([0, 1]) + ax.bar([0, 1, 2, 3], [0, 10, 20, 30], width=0.5, in_autoscale=False) + ax.margins(0) + ax.autoscale_view() + assert ax.get_xlim() == (0, 1) + assert ax.get_ylim() == (0, 1)