Skip to content

Switch transOffset to offset_transform. #21965

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
Jan 8, 2022
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
5 changes: 5 additions & 0 deletions doc/api/next_api_changes/deprecations/21965-AL.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
``transOffset`` parameter name
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``transOffset`` parameter of `.Collection.set_offset_transform` and the
various ``create_collection`` methods of legend handlers has been renamed to
``offset_transform`` (consistently with the property name).
2 changes: 1 addition & 1 deletion examples/event_handling/lasso_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def __init__(self, ax, data):
6, sizes=(100,),
facecolors=facecolors,
offsets=self.xys,
transOffset=ax.transData)
offset_transform=ax.transData)

ax.add_collection(self.collection)

Expand Down
14 changes: 7 additions & 7 deletions examples/shapes_and_collections/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

For the first two subplots, we will use spirals. Their size will be set in
plot units, not data units. Their positions will be set in data units by using
the *offsets* and *transOffset* keyword arguments of the `.LineCollection` and
`.PolyCollection`.
the *offsets* and *offset_transform* keyword arguments of the `.LineCollection`
and `.PolyCollection`.

The third subplot will make regular polygons, with the same
type of scaling and positioning as in the first two.
Expand Down Expand Up @@ -46,8 +46,8 @@
hspace=0.3, wspace=0.3)


col = collections.LineCollection([spiral], offsets=xyo,
transOffset=ax1.transData)
col = collections.LineCollection(
[spiral], offsets=xyo, offset_transform=ax1.transData)
trans = fig.dpi_scale_trans + transforms.Affine2D().scale(1.0/72.0)
col.set_transform(trans) # the points to pixels transform
# Note: the first argument to the collection initializer
Expand All @@ -71,8 +71,8 @@


# The same data as above, but fill the curves.
col = collections.PolyCollection([spiral], offsets=xyo,
transOffset=ax2.transData)
col = collections.PolyCollection(
[spiral], offsets=xyo, offset_transform=ax2.transData)
trans = transforms.Affine2D().scale(fig.dpi/72.0)
col.set_transform(trans) # the points to pixels transform
ax2.add_collection(col, autolim=True)
Expand All @@ -85,7 +85,7 @@
# 7-sided regular polygons

col = collections.RegularPolyCollection(
7, sizes=np.abs(xx) * 10.0, offsets=xyo, transOffset=ax3.transData)
7, sizes=np.abs(xx) * 10.0, offsets=xyo, offset_transform=ax3.transData)
trans = transforms.Affine2D().scale(fig.dpi / 72.0)
col.set_transform(trans) # the points to pixels transform
ax3.add_collection(col, autolim=True)
Expand Down
3 changes: 2 additions & 1 deletion examples/shapes_and_collections/ellipse_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
a `~.collections.EllipseCollection` or `~.collections.PathCollection`, the use
of an `~.collections.EllipseCollection` allows for much shorter code.
"""

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.collections import EllipseCollection
Expand All @@ -25,7 +26,7 @@
fig, ax = plt.subplots()

ec = EllipseCollection(ww, hh, aa, units='x', offsets=XY,
transOffset=ax.transData)
offset_transform=ax.transData)
ec.set_array((X + Y).ravel())
ax.add_collection(ec)
ax.autoscale_view()
Expand Down
2 changes: 1 addition & 1 deletion examples/specialty_plots/mri_with_eeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
offsets = np.zeros((n_rows, 2), dtype=float)
offsets[:, 1] = ticklocs

lines = LineCollection(segs, offsets=offsets, transOffset=None)
lines = LineCollection(segs, offsets=offsets, offset_transform=None)
ax2.add_collection(lines)

# Set the yticks to use axes coordinates on the y axis
Expand Down
21 changes: 11 additions & 10 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4463,14 +4463,14 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
offsets = np.ma.column_stack([x, y])

collection = mcoll.PathCollection(
(path,), scales,
facecolors=colors,
edgecolors=edgecolors,
linewidths=linewidths,
offsets=offsets,
transOffset=kwargs.pop('transform', self.transData),
alpha=alpha
)
(path,), scales,
facecolors=colors,
edgecolors=edgecolors,
linewidths=linewidths,
offsets=offsets,
offset_transform=kwargs.pop('transform', self.transData),
alpha=alpha,
)
collection.set_transform(mtransforms.IdentityTransform())
if colors is None:
collection.set_array(c)
Expand Down Expand Up @@ -4796,8 +4796,9 @@ def reduce_C_function(C: array) -> float
edgecolors=edgecolors,
linewidths=linewidths,
offsets=offsets,
transOffset=mtransforms.AffineDeltaTransform(self.transData),
)
offset_transform=mtransforms.AffineDeltaTransform(
self.transData),
)

# Set normalizer if bins is 'log'
if bins == 'log':
Expand Down
73 changes: 38 additions & 35 deletions lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"facecolor": ["facecolors", "fc"],
"linestyle": ["linestyles", "dashes", "ls"],
"linewidth": ["linewidths", "lw"],
"offset_transform": ["transOffset"],
})
class Collection(artist.Artist, cm.ScalarMappable):
r"""
Expand Down Expand Up @@ -84,7 +85,7 @@ def __init__(self,
joinstyle=None,
antialiaseds=None,
offsets=None,
transOffset=None,
offset_transform=None,
norm=None, # optional for ScalarMappable
cmap=None, # ditto
pickradius=5.0,
Expand Down Expand Up @@ -127,7 +128,7 @@ def __init__(self,
A vector by which to translate each patch after rendering (default
is no translation). The translation is performed in screen (pixel)
coordinates (i.e. after the Artist's transform is applied).
transOffset : `~.transforms.Transform`, default: `.IdentityTransform`
offset_transform : `~.Transform`, default: `.IdentityTransform`
A single transform which will be applied to each *offsets* vector
before it is used.
norm : `~.colors.Normalize`, optional
Expand Down Expand Up @@ -202,7 +203,7 @@ def __init__(self,
offsets = offsets[None, :]
self._offsets = offsets

self._transOffset = transOffset
self._offset_transform = offset_transform

self._path_effects = None
self.update(kwargs)
Expand All @@ -219,22 +220,24 @@ def get_transforms(self):

def get_offset_transform(self):
"""Return the `.Transform` instance used by this artist offset."""
if self._transOffset is None:
self._transOffset = transforms.IdentityTransform()
elif (not isinstance(self._transOffset, transforms.Transform)
and hasattr(self._transOffset, '_as_mpl_transform')):
self._transOffset = self._transOffset._as_mpl_transform(self.axes)
return self._transOffset
if self._offset_transform is None:
self._offset_transform = transforms.IdentityTransform()
elif (not isinstance(self._offset_transform, transforms.Transform)
and hasattr(self._offset_transform, '_as_mpl_transform')):
self._offset_transform = \
self._offset_transform._as_mpl_transform(self.axes)
return self._offset_transform

def set_offset_transform(self, transOffset):
@_api.rename_parameter("3.6", "transOffset", "offset_transform")
def set_offset_transform(self, offset_transform):
"""
Set the artist offset transform.

Parameters
----------
transOffset : `.Transform`
offset_transform : `.Transform`
"""
self._transOffset = transOffset
self._offset_transform = offset_transform

def get_datalim(self, transData):
# Calculate the data limits and return them as a `.Bbox`.
Expand All @@ -254,9 +257,9 @@ def get_datalim(self, transData):
# 3. otherwise return a null Bbox.

transform = self.get_transform()
transOffset = self.get_offset_transform()
hasOffsets = np.any(self._offsets) # True if any non-zero offsets
if hasOffsets and not transOffset.contains_branch(transData):
offset_trf = self.get_offset_transform()
has_offsets = np.any(self._offsets) # True if any non-zero offsets
if has_offsets and not offset_trf.contains_branch(transData):
# if there are offsets but in some coords other than data,
# then don't use them for autoscaling.
return transforms.Bbox.null()
Expand Down Expand Up @@ -284,16 +287,16 @@ def get_datalim(self, transData):
return mpath.get_path_collection_extents(
transform.get_affine() - transData, paths,
self.get_transforms(),
transOffset.transform_non_affine(offsets),
transOffset.get_affine().frozen())
if hasOffsets:
offset_trf.transform_non_affine(offsets),
offset_trf.get_affine().frozen())
if has_offsets:
# this is for collections that have their paths (shapes)
# in physical, axes-relative, or figure-relative units
# (i.e. like scatter). We can't uniquely set limits based on
# those shapes, so we just set the limits based on their
# location.

offsets = (transOffset - transData).transform(offsets)
offsets = (offset_trf - transData).transform(offsets)
# note A-B means A B^{-1}
offsets = np.ma.masked_invalid(offsets)
if not offsets.mask.all():
Expand All @@ -311,7 +314,7 @@ def _prepare_points(self):
# Helper for drawing and hit testing.

transform = self.get_transform()
transOffset = self.get_offset_transform()
offset_trf = self.get_offset_transform()
offsets = self._offsets
paths = self.get_paths()

Expand All @@ -332,17 +335,17 @@ def _prepare_points(self):
paths = [transform.transform_path_non_affine(path)
for path in paths]
transform = transform.get_affine()
if not transOffset.is_affine:
offsets = transOffset.transform_non_affine(offsets)
if not offset_trf.is_affine:
offsets = offset_trf.transform_non_affine(offsets)
# This might have changed an ndarray into a masked array.
transOffset = transOffset.get_affine()
offset_trf = offset_trf.get_affine()

if isinstance(offsets, np.ma.MaskedArray):
offsets = offsets.filled(np.nan)
# Changing from a masked array to nan-filled ndarray
# is probably most efficient at this point.

return transform, transOffset, offsets, paths
return transform, offset_trf, offsets, paths

@artist.allow_rasterization
def draw(self, renderer):
Expand All @@ -352,7 +355,7 @@ def draw(self, renderer):

self.update_scalarmappable()

transform, transOffset, offsets, paths = self._prepare_points()
transform, offset_trf, offsets, paths = self._prepare_points()

gc = renderer.new_gc()
self._set_gc_clip(gc)
Expand Down Expand Up @@ -408,11 +411,11 @@ def draw(self, renderer):
gc.set_url(self._urls[0])
renderer.draw_markers(
gc, paths[0], combined_transform.frozen(),
mpath.Path(offsets), transOffset, tuple(facecolors[0]))
mpath.Path(offsets), offset_trf, tuple(facecolors[0]))
else:
renderer.draw_path_collection(
gc, transform.frozen(), paths,
self.get_transforms(), offsets, transOffset,
self.get_transforms(), offsets, offset_trf,
self.get_facecolor(), self.get_edgecolor(),
self._linewidths, self._linestyles,
self._antialiaseds, self._urls,
Expand Down Expand Up @@ -459,7 +462,7 @@ def contains(self, mouseevent):
if self.axes:
self.axes._unstale_viewLim()

transform, transOffset, offsets, paths = self._prepare_points()
transform, offset_trf, offsets, paths = self._prepare_points()

# Tests if the point is contained on one of the polygons formed
# by the control points of each of the paths. A point is considered
Expand All @@ -469,7 +472,7 @@ def contains(self, mouseevent):
ind = _path.point_in_path_collection(
mouseevent.x, mouseevent.y, pickradius,
transform.frozen(), paths, self.get_transforms(),
offsets, transOffset, pickradius <= 0)
offsets, offset_trf, pickradius <= 0)

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

Expand Down Expand Up @@ -1317,7 +1320,7 @@ def __init__(self,
edgecolors=("black",),
linewidths=(1,),
offsets=offsets,
transOffset=ax.transData,
offset_transform=ax.transData,
)
"""
super().__init__(**kwargs)
Expand Down Expand Up @@ -2149,7 +2152,7 @@ def draw(self, renderer):
return
renderer.open_group(self.__class__.__name__, self.get_gid())
transform = self.get_transform()
transOffset = self.get_offset_transform()
offset_trf = self.get_offset_transform()
offsets = self._offsets

if self.have_units():
Expand All @@ -2168,9 +2171,9 @@ def draw(self, renderer):
else:
coordinates = self._coordinates

if not transOffset.is_affine:
offsets = transOffset.transform_non_affine(offsets)
transOffset = transOffset.get_affine()
if not offset_trf.is_affine:
offsets = offset_trf.transform_non_affine(offsets)
offset_trf = offset_trf.get_affine()

gc = renderer.new_gc()
gc.set_snap(self.get_snap())
Expand All @@ -2185,7 +2188,7 @@ def draw(self, renderer):
renderer.draw_quad_mesh(
gc, transform.frozen(),
coordinates.shape[1] - 1, coordinates.shape[0] - 1,
coordinates, offsets, transOffset,
coordinates, offsets, offset_trf,
# Backends expect flattened rgba arrays (n*m, 4) for fc and ec
self.get_facecolor().reshape((-1, 4)),
self._antialiased, self.get_edgecolors().reshape((-1, 4)))
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -829,8 +829,8 @@ def _auto_legend_data(self):
bboxes.append(
artist.get_path().get_extents(artist.get_transform()))
elif isinstance(artist, Collection):
_, transOffset, hoffsets, _ = artist._prepare_points()
for offset in transOffset.transform(hoffsets):
_, offset_trf, hoffsets, _ = artist._prepare_points()
for offset in offset_trf.transform(hoffsets):
offsets.append(offset)
return bboxes, lines, offsets

Expand Down
Loading