Skip to content

Commit 87a5d54

Browse files
committed
Deprecate offset_position="data".
The `offset_position` property of collections is currently set to "data" only for hexbin(), but one can do away with it by just setting the correct offsetTrans instead -- which this PR does. The advantage of doing so is that the correct offsetTrans only needs to be implemented once, whereas support for `offset_position` needs to be implemented for each renderer class separately (including at the C-level for the Agg backend). Note that the *offset_position* argument to `draw_path_collection` is not pending removal because its removal would require coordination with third-party backends; the plan is to just always set it to "screen" after the deprecation period. If there is demand for it, _VectorTransform could be made a public API.
1 parent 20387f7 commit 87a5d54

File tree

6 files changed

+81
-24
lines changed

6 files changed

+81
-24
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Deprecations
2+
````````````
3+
4+
The ``offset_position`` property of `Collection` is deprecated. In the future,
5+
`Collection`\s will always behave as if ``offset_position`` is set to "screen"
6+
(the default).
7+
8+
Support for passing ``offset_position="data"`` to the ``draw_path_collection``
9+
of all renderer classes is deprecated.

lib/matplotlib/axes/_axes.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -4769,8 +4769,7 @@ def hexbin(self, x, y, C=None, gridsize=100, bins=None,
47694769
edgecolors=edgecolors,
47704770
linewidths=linewidths,
47714771
offsets=offsets,
4772-
transOffset=mtransforms.IdentityTransform(),
4773-
offset_position="data"
4772+
transOffset=mtransforms._VectorTransform(self.transData),
47744773
)
47754774

47764775
# Check for valid norm

lib/matplotlib/backend_bases.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,10 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms,
215215
*linestyles* and *antialiaseds*. *offsets* is a list of
216216
offsets to apply to each of the paths. The offsets in
217217
*offsets* are first transformed by *offsetTrans* before being
218-
applied. *offset_position* may be either "screen" or "data"
219-
depending on the space that the offsets are in.
218+
applied.
219+
220+
*offset_position* may be either "screen" or "data" depending on the
221+
space that the offsets are in; "data" is deprecated.
220222
221223
This provides a fallback implementation of
222224
:meth:`draw_path_collection` that makes multiple calls to
@@ -391,6 +393,11 @@ def _iter_collection(self, gc, master_transform, all_transforms,
391393
Naa = len(antialiaseds)
392394
Nurls = len(urls)
393395

396+
if offset_position == "data":
397+
cbook.warn_deprecated(
398+
"3.1", message="Support for offset_position='data' is "
399+
"deprecated since %(since)s and will be removed %(removal)s.")
400+
394401
if (Nfacecolors == 0 and Nedgecolors == 0) or Npaths == 0:
395402
return
396403
if Noffsets:

lib/matplotlib/backends/backend_agg.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ def _update_methods(self):
104104
self.draw_gouraud_triangles = self._renderer.draw_gouraud_triangles
105105
self.draw_image = self._renderer.draw_image
106106
self.draw_markers = self._renderer.draw_markers
107-
self.draw_path_collection = self._renderer.draw_path_collection
107+
# This is its own method for the duration of the deprecation of
108+
# offset_position = "data".
109+
# self.draw_path_collection = self._renderer.draw_path_collection
108110
self.draw_quad_mesh = self._renderer.draw_quad_mesh
109111
self.copy_from_bbox = self._renderer.copy_from_bbox
110112
self.get_content_extents = self._renderer.get_content_extents
@@ -148,6 +150,19 @@ def draw_path(self, gc, path, transform, rgbFace=None):
148150
raise OverflowError("Exceeded cell block limit (set "
149151
"'agg.path.chunksize' rcparam)")
150152

153+
def draw_path_collection(self, gc, master_transform, paths, all_transforms,
154+
offsets, offsetTrans, facecolors, edgecolors,
155+
linewidths, linestyles, antialiaseds, urls,
156+
offset_position):
157+
if offset_position == "data":
158+
cbook.warn_deprecated(
159+
"3.1", message="Support for offset_position='data' is "
160+
"deprecated since %(since)s and will be removed %(removal)s.")
161+
return self._renderer.draw_path_collection(
162+
gc, master_transform, paths, all_transforms, offsets, offsetTrans,
163+
facecolors, edgecolors, linewidths, linestyles, antialiaseds, urls,
164+
offset_position)
165+
151166
def draw_mathtext(self, gc, x, y, s, prop, angle):
152167
"""
153168
Draw the math text using matplotlib.mathtext

lib/matplotlib/collections.py

+24-19
Original file line numberDiff line numberDiff line change
@@ -41,28 +41,28 @@ class Collection(artist.Artist, cm.ScalarMappable):
4141
4242
Keyword arguments and default values:
4343
44-
* *edgecolors*: None
45-
* *facecolors*: None
46-
* *linewidths*: None
47-
* *capstyle*: None
48-
* *joinstyle*: None
49-
* *antialiaseds*: None
50-
* *offsets*: None
51-
* *transOffset*: transforms.IdentityTransform()
52-
* *offset_position*: 'screen' (default) or 'data'
53-
* *norm*: None (optional for
54-
:class:`matplotlib.cm.ScalarMappable`)
55-
* *cmap*: None (optional for
56-
:class:`matplotlib.cm.ScalarMappable`)
57-
* *hatch*: None
58-
* *zorder*: 1
44+
* *edgecolors*: None
45+
* *facecolors*: None
46+
* *linewidths*: None
47+
* *capstyle*: None
48+
* *joinstyle*: None
49+
* *antialiaseds*: None
50+
* *offsets*: None
51+
* *transOffset*: transforms.IdentityTransform()
52+
* *offset_position* (deprecated): 'screen' (default) or 'data' (deprecated)
53+
* *norm*: None (optional for
54+
:class:`matplotlib.cm.ScalarMappable`)
55+
* *cmap*: None (optional for
56+
:class:`matplotlib.cm.ScalarMappable`)
57+
* *hatch*: None
58+
* *zorder*: 1
5959
6060
*offsets* and *transOffset* are used to translate the patch after
6161
rendering (default no offsets). If offset_position is 'screen'
6262
(default) the offset is applied after the master transform has
6363
been applied, that is, the offsets are in screen coordinates. If
64-
offset_position is 'data', the offset is applied before the master
65-
transform, i.e., the offsets are in data coordinates.
64+
offset_position is 'data' (deprecated), the offset is applied before the
65+
master transform, i.e., the offsets are in data coordinates.
6666
6767
If any of *edgecolors*, *facecolors*, *linewidths*, *antialiaseds*
6868
are None, they default to their :data:`matplotlib.rcParams` patch
@@ -87,6 +87,7 @@ class Collection(artist.Artist, cm.ScalarMappable):
8787
# subclass-by-subclass basis.
8888
_edge_default = False
8989

90+
@cbook._delete_parameter("3.1", "offset_position")
9091
def __init__(self,
9192
edgecolors=None,
9293
facecolors=None,
@@ -132,7 +133,9 @@ def __init__(self,
132133
self.set_pickradius(pickradius)
133134
self.set_urls(urls)
134135
self.set_hatch(hatch)
135-
self.set_offset_position(offset_position)
136+
self._offset_position = "screen"
137+
if offset_position != "screen":
138+
self.set_offset_position(offset_position) # emit deprecation.
136139
self.set_zorder(zorder)
137140

138141
if capstyle:
@@ -371,7 +374,7 @@ def contains(self, mouseevent):
371374
mouseevent.x, mouseevent.y, pickradius,
372375
transform.frozen(), paths, self.get_transforms(),
373376
offsets, transOffset, pickradius <= 0,
374-
self.get_offset_position())
377+
self._offset_position)
375378

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

@@ -452,6 +455,7 @@ def get_offsets(self):
452455
else:
453456
return self._uniform_offsets
454457

458+
@cbook.deprecated("3.1")
455459
def set_offset_position(self, offset_position):
456460
"""
457461
Set how offsets are applied. If *offset_position* is 'screen'
@@ -469,6 +473,7 @@ def set_offset_position(self, offset_position):
469473
self._offset_position = offset_position
470474
self.stale = True
471475

476+
@cbook.deprecated("3.1")
472477
def get_offset_position(self):
473478
"""
474479
Returns how offsets are applied for the collection. If

lib/matplotlib/transforms.py

+22
Original file line numberDiff line numberDiff line change
@@ -2680,6 +2680,28 @@ def get_matrix(self):
26802680
return self._mtx
26812681

26822682

2683+
class _VectorTransform(Affine2DBase):
2684+
"""
2685+
A transform wrapper that ignores the offset component of a base transform.
2686+
"""
2687+
2688+
def __init__(self, transform, **kwargs):
2689+
super().__init__(**kwargs)
2690+
self._base_transform = transform
2691+
2692+
def __str__(self):
2693+
return ("{}(\n"
2694+
"{})"
2695+
.format(type(self).__name__,
2696+
_indent_str(self._base_transform)))
2697+
2698+
def get_matrix(self):
2699+
if self._invalid:
2700+
self._mtx = self._base_transform.get_matrix().copy()
2701+
self._mtx[:2, -1] = 0
2702+
return self._mtx
2703+
2704+
26832705
class TransformedPath(TransformNode):
26842706
"""
26852707
A :class:`TransformedPath` caches a non-affine transformed copy of

0 commit comments

Comments
 (0)