8000 Merge pull request #22946 from greglucas/coll-no-offset2 · matplotlib/matplotlib@7c19d85 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7c19d85

Browse files
authored
Merge pull request #22946 from greglucas/coll-no-offset2
FIX: Handle no-offsets in collection datalim (alternative)
2 parents e9e62ea + e953840 commit 7c19d85

File tree

2 files changed

+43
-33
lines changed

2 files changed

+43
-33
lines changed

lib/matplotlib/collections.py

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ class Collection(artist.Artist, cm.ScalarMappable):
6262
mappable will be used to set the ``facecolors`` and ``edgecolors``,
6363
ignoring those that were manually passed in.
6464
"""
65-
_offsets = np.zeros((0, 2))
6665
#: Either a list of 3x3 arrays or an Nx3x3 array (representing N
6766
#: transforms), suitable for the `all_transforms` argument to
6867
#: `~matplotlib.backend_bases.RendererBase.draw_path_collection`;
@@ -193,15 +192,12 @@ 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
200+
self._offsets = offsets
205201

206202
self._offset_transform = offset_transform
207203

@@ -263,9 +259,12 @@ def get_datalim(self, transData):
263259
# if the offsets are in some coords other than data,
264260
# then don't use them for autoscaling.
265261
return transforms.Bbox.null()
266-
offsets = self._offsets
262+
offsets = self.get_offsets()
267263

268264
paths = self.get_paths()
265+
if not len(paths):
266+
# No paths to transform
267+
return transforms.Bbox.null()
269268

270269
if not transform.is_affine:
271270
paths = [transform.transform_path_non_affine(p) for p in paths]
@@ -274,22 +273,22 @@ def get_datalim(self, transData):
274273
# transforms.get_affine().contains_branch(transData). But later,
275274
# be careful to only apply the affine part that remains.
276275

277-
if isinstance(offsets, np.ma.MaskedArray):
278-
offsets = offsets.filled(np.nan)
279-
# get_path_collection_extents handles nan but not masked arrays
280-
281-
if len(paths) and len(offsets):
282-
if any(transform.contains_branch_seperately(transData)):
283-
# collections that are just in data units (like quiver)
284-
# can properly have the axes limits set by their shape +
285-
# offset. LineCollections that have no offsets can
286-
# also use this algorithm (like streamplot).
287-
return mpath.get_path_collection_extents(
288-
transform.get_affine() - transData, paths,
289-
self.get_transforms(),
290-
offset_trf.transform_non_affine(offsets),
291-
offset_trf.get_affine().frozen())
292-
276+
if any(transform.contains_branch_seperately(transData)):
277+
# collections that are just in data units (like quiver)
278+
# can properly have the axes limits set by their shape +
279+
# offset. LineCollections that have no offsets can
280+
# also use this algorithm (like streamplot).
281+
if isinstance(offsets, np.ma.MaskedArray):
282+
offsets = offsets.filled(np.nan)
283+
# get_path_collection_extents handles nan but not masked arrays
284+
return mpath.get_path_collection_extents(
285+
transform.get_affine() - transData, paths,
286+
self.get_transforms(),
287+
offset_trf.transform_non_affine(offsets),
288+
offset_trf.get_affine().frozen())
289+
290+
# NOTE: None is the default case where no offsets were passed in
291+
if self._offsets is not None:
293292
# this is for collections that have their paths (shapes)
294293
# in physical, axes-relative, or figure-relative units
295294
# (i.e. like scatter). We can't uniquely set limits based on
@@ -314,7 +313,7 @@ def _prepare_points(self):
314313

315314
transform = self.get_transform()
316315
offset_trf = self.get_offset_transform()
317-
offsets = self._offsets
316+
offsets = self.get_offsets()
318317
paths = self.get_paths()
319318

320319
if self.have_units():
@@ -325,10 +324,9 @@ def _prepare_points(self):
325324
xs = self.convert_xunits(xs)
326325
ys = self.convert_yunits(ys)
327326
paths.append(mpath.Path(np.column_stack([xs, ys]), path.codes))
328-
if offsets.size:
329-
xs = self.convert_xunits(offsets[:, 0])
330-
ys = self.convert_yunits(offsets[:, 1])
331-
offsets = np.column_stack([xs, ys])
327+
xs = self.convert_xunits(offsets[:, 0])
328+
ys = self.convert_yunits(offsets[:, 1])
329+
offsets = np.column_stack([xs, ys])
332330

333331
if not transform.is_affine:
334332
paths = [transform.transform_path_non_affine(path)
@@ -557,7 +555,8 @@ def set_offsets(self, offsets):
557555

558556
def get_offsets(self):
559557
"""Return the offsets for the collection."""
560-
return self._offsets
558+
# Default to zeros in the no-offset (None) case
559+
return np.zeros((1, 2)) if self._offsets is None else self._offsets
561560

562561
def _get_default_linewidth(self):
563562
# This may be overridden in a subclass.
@@ -2154,13 +2153,12 @@ def draw(self, renderer):
21542153
renderer.open_group(self.__class__.__name__, self.get_gid())
21552154
transform = self.get_transform()
21562155
offset_trf = self.get_offset_transform()
2157-
offsets = self._offsets
2156+
offsets = self.get_offsets()
21582157

21592158
if self.have_units():
2160-
if len(self._offsets):
2161-
xs = self.convert_xunits(self._offsets[:, 0])
2162-
ys = self.convert_yunits(self._offsets[:, 1])
2163-
offsets = np.column_stack([xs, ys])
2159+
xs = self.convert_xunits(offsets[:, 0])
2160+
ys = self.convert_yunits(offsets[:, 1])
2161+
offsets = np.column_stack([xs, ys])
21642162

21652163
self.update_scalarmappable()
21662164

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)
0