Skip to content

Commit 88b722f

Browse files
committed
Fixed bad quiver transforms.
1 parent 5bc2357 commit 88b722f

File tree

7 files changed

+76
-32
lines changed

7 files changed

+76
-32
lines changed

lib/matplotlib/axes.py

+3-7
Original file line numberDiff line numberDiff line change
@@ -1474,10 +1474,7 @@ def add_collection(self, collection, autolim=True):
14741474
if collection.get_clip_path() is None:
14751475
collection.set_clip_path(self.patch)
14761476

1477-
if (autolim and
1478-
collection._paths is not None and
1479-
len(collection._paths) and
1480-
len(collection._offsets)):
1477+
if autolim:
14811478
self.update_datalim(collection.get_datalim(self.transData))
14821479

14831480
collection._remove_method = lambda h: self.collections.remove(h)
@@ -6834,8 +6831,8 @@ def quiver(self, *args, **kw):
68346831
if not self._hold:
68356832
self.cla()
68366833
q = mquiver.Quiver(self, *args, **kw)
6837-
self.add_collection(q, False)
6838-
self.update_datalim(q.XY)
6834+
6835+
self.add_collection(q, True)
68396836
self.autoscale_view()
68406837
return q
68416838
quiver.__doc__ = mquiver.Quiver.quiver_doc
@@ -6875,7 +6872,6 @@ def barbs(self, *args, **kw):
68756872
self.cla()
68766873
b = mquiver.Barbs(self, *args, **kw)
68776874
self.add_collection(b)
6878-
self.update_datalim(b.get_offsets())
68796875
self.autoscale_view()
68806876
return b
68816877

lib/matplotlib/collections.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,13 @@ def get_datalim(self, transData):
188188
# get_path_collection_extents handles nan but not masked arrays
189189
offsets.shape = (-1, 2) # Make it Nx2
190190

191-
if paths:
191+
if len(paths) and len(offsets):
192192
result = mpath.get_path_collection_extents(
193193
transform.frozen(), paths, self.get_transforms(),
194194
offsets, transOffset.frozen())
195195
result = result.inverse_transformed(transData)
196196
else:
197-
result = transforms.Bbox([[0, 0], [0, 0]])
197+
result = transforms.Bbox.null()
198198
return result
199199

200200
def get_window_extent(self, renderer):
@@ -1710,9 +1710,6 @@ def convert_mesh_to_triangles(self, meshWidth, meshHeight, coordinates):
17101710

17111711
return triangles, colors
17121712

1713-
def get_datalim(self, transData):
1714-
return self._bbox
1715-
17161713
@allow_rasterization
17171714
def draw(self, renderer):
17181715
if not self.get_visible():

lib/matplotlib/quiver.py

+9
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,15 @@ def _init(self):
448448
sn = max(8, min(25, math.sqrt(self.N)))
449449
self.width = 0.06 * self.span / sn
450450

451+
def get_datalim(self, transData):
452+
trans = self.get_transform()
453+
transOffset = self.get_offset_transform()
454+
full_transform = (trans - transData) + (transOffset - transData)
455+
XY = full_transform.transform(self.XY)
456+
bbox = transforms.Bbox.null()
457+
bbox.update_from_data_xy(XY, ignore=True)
458+
return bbox
459+
451460
@allow_rasterization
452461
def draw(self, renderer):
453462
self._init()

lib/matplotlib/streamplot.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,7 @@ def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None,
168168
lc.set_cmap(cmap)
169169
lc.set_norm(norm)
170170
axes.add_collection(lc)
171-
172-
axes.update_datalim(((x.min(), y.min()), (x.max(), y.max())))
173-
axes.autoscale_view(tight=True)
171+
axes.autoscale_view()
174172

175173
ac = matplotlib.collections.PatchCollection(arrows)
176174
stream_container = StreamplotSet(lc, ac)

lib/matplotlib/tests/test_axes.py

+1-14
Original file line numberDiff line numberDiff line change
@@ -58,20 +58,6 @@ def test_formatter_ticker():
5858
ax.set_xlabel( "x-label 005" )
5959
ax.autoscale_view()
6060

61-
@cleanup
62-
def test_add_collection():
63-
# Test if data limits are unchanged by adding an empty collection.
64-
# Github issue #1490, pull #1497.
65-
fig = matplotlib.figure.Figure()
66-
fig2 = matplotlib.figure.Figure()
67-
ax = fig.add_subplot(111)
68-
ax2 = fig2.add_subplot(111)
69-
coll = ax2.scatter([0, 1], [0, 1])
70-
ax.add_collection(coll)
71-
bounds = ax.dataLim.bounds
72-
coll = ax2.scatter([], [])
73-
ax.add_collection(coll)
74-
assert ax.dataLim.bounds == bounds
7561

7662
@image_comparison(baseline_images=["formatter_large_small"])
7763
def test_formatter_large_small():
@@ -81,6 +67,7 @@ def test_formatter_large_small():
8167
y = [1e64, 1.1e64]
8268
ax.plot(x, y)
8369

70+
8471
@image_comparison(baseline_images=["twin_axis_locaters_formatters"])
8572
def test_twin_axis_locaters_formatters():
8673
vals = np.linspace(0, 1, num=5, endpoint=True)

lib/matplotlib/tests/test_collections.py

+42-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from nose.tools import assert_equal
66
import numpy as np
7-
from numpy.testing import assert_array_equal
7+
from numpy.testing import assert_array_equal, assert_array_almost_equal
88

99
import matplotlib.pyplot as plt
1010
import matplotlib.collections as mcollections
@@ -396,9 +396,49 @@ def test_null_collection_datalim():
396396
col = mcollections.PathCollection([])
397397
col_data_lim = col.get_datalim(mtransforms.IdentityTransform())
398398
assert_array_equal(col_data_lim.get_points(),
399-
mtransforms.Bbox([[0, 0], [0, 0]]).get_points())
399+
mtransforms.Bbox.null().get_points())
400400

401401

402+
@cleanup
403+
def test_add_collection():
404+
# Test if data limits are unchanged by adding an empty collection.
405+
# Github issue #1490, pull #1497.
406+
ax = plt.axes()
407+
plt.figure()
408+
ax2 = plt.axes()
409+
coll = ax2.scatter([0, 1], [0, 1])
410+
ax.add_collection(coll)
411+
bounds = ax.dataLim.bounds
412+
coll = ax2.scatter([], [])
413+
ax.add_collection(coll)
414+
assert_equal(ax.dataLim.bounds, bounds)
415+
416+
417+
@cleanup
418+
def test_quiver_limits():
419+
ax = plt.axes()
420+
x = np.linspace(-5, 10, 20)
421+
y = np.linspace(-2, 4, 10)
422+
y, x = np.meshgrid(y, x)
423+
trans = mtransforms.Affine2D().translate(25, 32) + ax.transData
424+
plt.quiver(x, y, np.sin(x), np.cos(y), transform=trans)
425+
assert_equal(ax.dataLim.bounds, (20.0, 30.0, 15.0, 6.0))
426+
427+
428+
@cleanup
429+
def test_barb_limits():
430+
ax = plt.axes()
431+
x = np.linspace(-5, 10, 20)
432+
y = np.linspace(-2, 4, 10)
433+
y, x = np.meshgrid(y, x)
434+
trans = mtransforms.Affine2D().translate(25, 32) + ax.transData
435+
plt.barbs(x, y, np.sin(x), np.cos(y), transform=trans)
436+
# The calculated bounds are approximately the bounds of the original data,
437+
# this is because the entire path is taken into account when updating the
438+
# datalim.
439+
assert_array_almost_equal(ax.dataLim.bounds, (20, 30, 15, 6),
440+
decimal=2)
441+
402442
if __name__ == '__main__':
403443
import nose
404444
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

lib/matplotlib/tests/test_streamplot.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import numpy as np
2+
from numpy.testing import assert_array_almost_equal
23
import matplotlib.pyplot as plt
3-
from matplotlib.testing.decorators import image_comparison
4+
from matplotlib.testing.decorators import image_comparison, cleanup
5+
import matplotlib.transforms as mtransforms
46

57

68
def velocity_field():
@@ -36,6 +38,21 @@ def test_masks_and_nans():
3638
plt.streamplot(X, Y, U, V, color=U, cmap=plt.cm.Blues)
3739

3840

41+
@cleanup
42+
def test_streamplot_limits():
43+
ax = plt.axes()
44+
x = np.linspace(-5, 10, 20)
45+
y = np.linspace(-2, 4, 10)
46+
y, x = np.meshgrid(y, x)
47+
trans = mtransforms.Affine2D().translate(25, 32) + ax.transData
48+
plt.barbs(x, y, np.sin(x), np.cos(y), transform=trans)
49+
# The calculated bounds are approximately the bounds of the original data,
50+
# this is because the entire path is taken into account when updating the
51+
# datalim.
52+
assert_array_almost_equal(ax.dataLim.bounds, (20, 30, 15, 6),
53+
decimal=2)
54+
55+
3956
if __name__=='__main__':
4057
import nose
4158
nose.runmodule()

0 commit comments

Comments
 (0)