Skip to content

Deprecate offset_position="data". #13696

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions doc/api/api_changes_3.3/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -475,3 +475,15 @@ is deprecated; use the explicit defaults of 1 and 0, respectively, instead.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
... is deprecated. Scale ``Figure.dpi_scale_trans`` by 1/72 to achieve the
same effect.

``offset_position`` property of `.Collection`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``offset_position`` property of `.Collection` is deprecated. In the
future, `.Collection`\s will always behave as if ``offset_position`` is set to
"screen" (the default).

Support for passing ``offset_position="data"`` to the ``draw_path_collection``
of all renderer classes is deprecated.

`.transforms.AffineDeltaTransform` can be used as a replacement. This API is
experimental and may change in the future.
3 changes: 1 addition & 2 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4816,8 +4816,7 @@ def reduce_C_function(C: array) -> float
edgecolors=edgecolors,
linewidths=linewidths,
offsets=offsets,
transOffset=mtransforms.IdentityTransform(),
offset_position="data"
transOffset=mtransforms.AffineDeltaTransform(self.transData),
)

# Set normalizer if bins is 'log'
Expand Down
11 changes: 9 additions & 2 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,10 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms,
*linestyles* and *antialiaseds*. *offsets* is a list of
offsets to apply to each of the paths. The offsets in
*offsets* are first transformed by *offsetTrans* before being
applied. *offset_position* may be either "screen" or "data"
depending on the space that the offsets are in.
applied.

*offset_position* may be either "screen" or "data" depending on the
space that the offsets are in; "data" is deprecated.

This provides a fallback implementation of
:meth:`draw_path_collection` that makes multiple calls to
Expand Down Expand Up @@ -380,6 +382,11 @@ def _iter_collection(self, gc, master_transform, all_transforms,
Naa = len(antialiaseds)
Nurls = len(urls)

if offset_position == "data":
cbook.warn_deprecated(
"3.3", message="Support for offset_position='data' is "
"deprecated since %(since)s and will be removed %(removal)s.")

if (Nfacecolors == 0 and Nedgecolors == 0) or Npaths == 0:
return
if Noffsets:
Expand Down
17 changes: 16 additions & 1 deletion lib/matplotlib/backends/backend_agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ def _update_methods(self):
self.draw_gouraud_triangles = self._renderer.draw_gouraud_triangles
self.draw_image = self._renderer.draw_image
self.draw_markers = self._renderer.draw_markers
self.draw_path_collection = self._renderer.draw_path_collection
# This is its own method for the duration of the deprecation of
# offset_position = "data".
# self.draw_path_collection = self._renderer.draw_path_collection
self.draw_quad_mesh = self._renderer.draw_quad_mesh
self.copy_from_bbox = self._renderer.copy_from_bbox
self.get_content_extents = self._renderer.get_content_extents
Expand Down Expand Up @@ -155,6 +157,19 @@ def draw_path(self, gc, path, transform, rgbFace=None):
raise OverflowError("Exceeded cell block limit (set "
"'agg.path.chunksize' rcparam)") from err

def draw_path_collection(self, gc, master_transform, paths, all_transforms,
offsets, offsetTrans, facecolors, edgecolors,
linewidths, linestyles, antialiaseds, urls,
offset_position):
if offset_position == "data":
cbook.warn_deprecated(
"3.3", message="Support for offset_position='data' is "
"deprecated since %(since)s and will be removed %(removal)s.")
return self._renderer.draw_path_collection(
gc, master_transform, paths, all_transforms, offsets, offsetTrans,
facecolors, edgecolors, linewidths, linestyles, antialiaseds, urls,
offset_position)

def draw_mathtext(self, gc, x, y, s, prop, angle):
"""Draw mathtext using :mod:`matplotlib.mathtext`."""
ox, oy, width, height, descent, font_image, used_characters = \
Expand Down
17 changes: 11 additions & 6 deletions lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class Collection(artist.Artist, cm.ScalarMappable):
- *antialiaseds*: None
- *offsets*: None
- *transOffset*: transforms.IdentityTransform()
- *offset_position*: 'screen' (default) or 'data'
- *offset_position* (deprecated): 'screen' (default) or 'data' (deprecated)
- *norm*: None (optional for `matplotlib.cm.ScalarMappable`)
- *cmap*: None (optional for `matplotlib.cm.ScalarMappable`)
- *hatch*: None
Expand All @@ -59,8 +59,8 @@ class Collection(artist.Artist, cm.ScalarMappable):
rendering (default no offsets). If offset_position is 'screen'
(default) the offset is applied after the master transform has
been applied, that is, the offsets are in screen coordinates. If
offset_position is 'data', the offset is applied before the master
transform, i.e., the offsets are in data coordinates.
offset_position is 'data' (deprecated), the offset is applied before the
master transform, i.e., the offsets are in data coordinates.

If any of *edgecolors*, *facecolors*, *linewidths*, *antialiaseds* are
None, they default to their `.rcParams` patch setting, in sequence form.
Expand All @@ -85,6 +85,7 @@ class Collection(artist.Artist, cm.ScalarMappable):
# subclass-by-subclass basis.
_edge_default = False

@cbook._delete_parameter("3.3", "offset_position")
def __init__(self,
edgecolors=None,
facecolors=None,
Expand Down Expand Up @@ -130,7 +131,9 @@ def __init__(self,
self.set_pickradius(pickradius)
self.set_urls(urls)
self.set_hatch(hatch)
self.set_offset_position(offset_position)
self._offset_position = "screen"
if offset_position != "screen":
self.set_offset_position(offset_position) # emit deprecation.
self.set_zorder(zorder)

if capstyle:
Expand Down Expand Up @@ -404,7 +407,7 @@ def contains(self, mouseevent):
self._picker is not True # the bool, not just nonzero or 1
else self._pickradius)

if self.axes and self.get_offset_position() == "data":
if self.axes:
self.axes._unstale_viewLim()

transform, transOffset, offsets, paths = self._prepare_points()
Expand All @@ -413,7 +416,7 @@ def contains(self, mouseevent):
mouseevent.x, mouseevent.y, pickradius,
transform.frozen(), paths, self.get_transforms(),
offsets, transOffset, pickradius <= 0,
self.get_offset_position())
self._offset_position)

return len(ind) > 0, dict(ind=ind)

Expand Down Expand Up @@ -494,6 +497,7 @@ def get_offsets(self):
else:
return self._uniform_offsets

@cbook.deprecated("3.3")
def set_offset_position(self, offset_position):
"""
Set how offsets are applied. If *offset_position* is 'screen'
Expand All @@ -511,6 +515,7 @@ def set_offset_position(self, offset_position):
self._offset_position = offset_position
self.stale = True

@cbook.deprecated("3.3")
def get_offset_position(self):
"""
Return how offsets are applied for the collection. If
Expand Down
11 changes: 6 additions & 5 deletions lib/matplotlib/tests/test_backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ def check(master_transform, paths, all_transforms,
master_transform, paths, all_transforms))
gc = rb.new_gc()
ids = [path_id for xo, yo, path_id, gc0, rgbFace in
rb._iter_collection(gc, master_transform, all_transforms,
range(len(raw_paths)), offsets,
transforms.IdentityTransform(),
facecolors, edgecolors, [], [], [False],
[], 'data')]
rb._iter_collection(
gc, master_transform, all_transforms,
range(len(raw_paths)), offsets,
transforms.AffineDeltaTransform(master_transform),
facecolors, edgecolors, [], [], [False],
[], 'screen')]
uses = rb._iter_collection_uses_per_path(
paths, all_transforms, offsets, facecolors, edgecolors)
if raw_paths:
Expand Down
30 changes: 30 additions & 0 deletions lib/matplotlib/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2617,6 +2617,36 @@ def get_matrix(self):
return self._mtx


class AffineDeltaTransform(Affine2DBase):
r"""
A transform wrapper for transforming displacements between pairs of points.

This class is intended to be used to transform displacements ("position
deltas") between pairs of points (e.g., as the ``offset_transform``
of `.Collection`\s): given a transform ``t`` such that ``t =
AffineDeltaTransform(t) + offset``, ``AffineDeltaTransform``
satisfies ``AffineDeltaTransform(a - b) == AffineDeltaTransform(a) -
AffineDeltaTransform(b)``.

This is implemented by forcing the offset components of the transform
matrix to zero.

This class is experimental as of 3.3, and the API may change.
"""

def __init__(self, transform, **kwargs):
super().__init__(**kwargs)
self._base_transform = transform

__str__ = _make_str_method("_base_transform")

def get_matrix(self):
if self._invalid:
self._mtx = self._base_transform.get_matrix().copy()
self._mtx[:2, -1] = 0
return self._mtx


class TransformedPath(TransformNode):
"""
A `TransformedPath` caches a non-affine transformed copy of the
Expand Down