Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b262b11

Browse files
timhoffmgreglucas
authored andcommitted
Backport PR matplotlib#22946: FIX: Handle no-offsets in collection datalim (alternative)
1 parent 930bb82 commit b262b11

File tree

2 files changed

+42
-32
lines changed

2 files changed

+42
-32
lines changed

‎lib/matplotlib/collections.py

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ class Collection(artist.Artist, cm.ScalarMappable):
6161
mappable will be used to set the ``facecolors`` and ``edgecolors``,
6262
ignoring those that were manually passed in.
6363
"""
64-
_offsets = np.zeros((0, 2))
6564
#: Either a list of 3x3 arrays or an Nx3x3 array (representing N
6665
#: transforms), suitable for the `all_transforms` argument to
6766
#: `~matplotlib.backend_bases.RendererBase.draw_path_collection`;
@@ -193,15 +192,11 @@ def __init__(self,
193192
else:
194193
self._joinstyle = None
195194

196-
# default to zeros
197-
self._offsets = np.zeros((1, 2))
198-
199195
if offsets is not None:
200196
offsets = np.asanyarray(offsets, float)
201197
# Broadcast (2,) -> (1, 2) but nothing else.
202198
if offsets.shape == (2,):
203199
offsets = offsets[None, :]
204-
self._offsets = offsets
205200
elif transOffset is not None:
206201
_api.warn_deprecated(
207202
'3.5',
@@ -215,6 +210,7 @@ def __init__(self,
215210
'explicitly.')
216211
transOffset = None
217212

213+
self._offsets = offsets
218214
self._transOffset = transOffset
219215

220216
self._path_effects = None
@@ -273,9 +269,12 @@ def get_datalim(self, transData):
273269
# if there are offsets but in some coords other than data,
274270
# then don't use them for autoscaling.
275271
return transforms.Bbox.null()
276-
offsets = self._offsets
272+
offsets = self.get_offsets()
277273

278274
paths = self.get_paths()
275+
if not len(paths):
276+
# No paths to transform
277+
return transforms.Bbox.null()
279278

280279
if not transform.is_affine:
281280
paths = [transform.transform_path_non_affine(p) for p in paths]
@@ -284,22 +283,22 @@ def get_datalim(self, transData):
284283
# transforms.get_affine().contains_branch(transData). But later,
285284
# be careful to only apply the affine part that remains.
286285

287-
if isinstance(offsets, np.ma.MaskedArray):
288-
offsets = offsets.filled(np.nan)
286+
if any(transform.contains_branch_seperately(transData)):
287+
if isinstance(offsets, np.ma.MaskedArray):
288+
offsets = offsets.filled(np.nan)
289289
# get_path_collection_extents handles nan but not masked arrays
290-
291-
if len(paths) and len(offsets):
292-
if any(transform.contains_branch_seperately(transData)):
293-
# collections that are just in data units (like quiver)
294-
# can properly have the axes limits set by their shape +
295-
# offset. LineCollections that have no offsets can
296-
# also use this algorithm (like streamplot).
297-
return mpath.get_path_collection_extents(
298-
transform.get_affine() - transData, paths,
299-
self.get_transforms(),
300-
transOffset.transform_non_affine(offsets),
301-
transOffset.get_affine().frozen())
302-
290+
# collections that are just in data units (like quiver)
291+
# can properly have the axes limits set by their shape +
292+
# offset. LineCollections that have no offsets can
293+
# also use this algorithm (like streamplot).
294+
return mpath.get_path_collection_extents(
295+
transform.get_affine() - transData, paths,
296+
self.get_transforms(),
297+
transOffset.transform_non_affine(offsets),
298+
transOffset.get_affine().frozen())
299+
300+
# NOTE: None is the default case where no offsets were passed in
301+
if self._offsets is not None:
303302
# this is for collections that have their paths (shapes)
304303
# in physical, axes-relative, or figure-relative units
305304
# (i.e. like scatter). We can't uniquely set limits based on
@@ -325,7 +324,7 @@ def _prepare_points(self):
325324

326325
transform = self.get_transform()
327326
transOffset = self.get_offset_transform()
328-
offsets = self._offsets
327+
offsets = self.get_offsets()
329328
paths = self.get_paths()
330329

331330
if self.have_units():
@@ -336,10 +335,9 @@ def _prepare_points(self):
336335
xs = self.convert_xunits(xs)
337336
ys = self.convert_yunits(ys)
338337
paths.append(mpath.Path(np.column_stack([xs, ys]), path.codes))
339-
if offsets.size:
340-
xs = self.convert_xunits(offsets[:, 0])
341-
ys = self.convert_yunits(offsets[:, 1])
342-
offsets = np.column_stack([xs, ys])
338+
xs = self.convert_xunits(offsets[:, 0])
339+
ys = self.convert_yunits(offsets[:, 1])
340+
offsets = np.column_stack([xs, ys])
343341

344342
if not transform.is_affine:
345343
paths = [transform.transform_path_non_affine(path)
@@ -569,7 +567,8 @@ def set_offsets(self, offsets):
569567

570568
def get_offsets(self):
571569
"""Return the offsets for the collection."""
572-
return self._offsets
570+
# Default to zeros in the no-offset (None) case
571+
return np.zeros((1, 2)) if self._offsets is None else self._offsets
573572

574573
def _get_default_linewidth(self):
575574
# This may be overridden in a subclass.
@@ -2166,13 +2165,12 @@ def draw(self, renderer):
21662165
renderer.open_group(self.__class__.__name__, self.get_gid())
21672166
transform = self.get_transform()
21682167
transOffset = self.get_offset_transform()
2169-
offsets = self._offsets
2168+
offsets = self.get_offsets()
21702169

21712170
if self.have_units():
2172-
if len(self._offsets):
2173-
xs = self.convert_xunits(self._offsets[:, 0])
2174-
ys = self.convert_yunits(self._offsets[:, 1])
2175-
offsets = np.column_stack([xs, ys])
2171+
xs = self.convert_xunits(offsets[:, 0])
2172+
ys = self.convert_yunits(offsets[:, 1])
2173+
offsets = np.column_stack([xs, ys])
21762174

21772175
self.update_scalarmappable()
21782176

‎lib/matplotlib/tests/test_collections.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import matplotlib.pyplot as plt
1010
import matplotlib.collections as mcollections
1111
import matplotlib.colors as mcolors
12+
import matplotlib.path as mpath
1213
import matplotlib.transforms as mtransforms
1314
from matplotlib.collections import (Collection, LineCollection,
1415
EventCollection, PolyCollection)
@@ -291,6 +292,17 @@ def test_null_collection_datalim():
291292
mtransforms.Bbox.null().get_points())
292293

293294

295+
def test_no_offsets_datalim():
296+
# A collection with no offsets and a non transData
297+
# transform should return a null bbox
298+
ax = plt.axes()
299+
coll = mcollections.PathCollection([mpath.Path([(0, 0), (1, 0)])])
300+
ax.add_collection(coll)
301+
coll_data_lim = coll.get_datalim(mtransforms.IdentityTransform())
302+
assert_array_equal(coll_data_lim.get_points(),
303+
mtransforms.Bbox.null().get_points())
304+
305+
294306
def test_add_collection():
295307
# Test if data limits are unchanged by adding an empty collection.
296308
# GitHub issue #1490, pull #1497.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /