Skip to content

Commit

Permalink
Merge pull request #2444 from pelson/quiver_trans
Browse files Browse the repository at this point in the history
Fixed bad vector transforms.
  • Loading branch information
tacaswell committed Feb 27, 2014
2 parents 53573c9 + 77e7628 commit 169a2f6
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 35 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Expand Up @@ -36,4 +36,5 @@ script:
after_failure:
- tar cjf result_images.tar.bz2 result_images
- travis-artifacts upload --path result_images.tar.bz2
- echo https://s3.amazonaws.com/matplotlib-test-results/artifacts/${TRAVIS_BUILD_NUMBER}/${TRAVIS_JOB_NUMBER}/result_images.tar.bz2
- echo "The result images will only be uploaded if they are on the matplotlib/matplotlib repo - this is for security reasons to prevent arbitrary PRs echoing security details."
- echo https://s3.amazonaws.com/matplotlib-test-results/artifacts/${TRAVIS_BUILD_NUMBER}/${TRAVIS_JOB_NUMBER}/result_images.tar.bz2
10 changes: 3 additions & 7 deletions lib/matplotlib/axes.py
Expand Up @@ -1474,10 +1474,7 @@ def add_collection(self, collection, autolim=True):
if collection.get_clip_path() is None:
collection.set_clip_path(self.patch)

if (autolim and
collection._paths is not None and
len(collection._paths) and
len(collection._offsets)):
if autolim:
self.update_datalim(collection.get_datalim(self.transData))

collection._remove_method = lambda h: self.collections.remove(h)
Expand Down Expand Up @@ -6842,8 +6839,8 @@ def quiver(self, *args, **kw):
if not self._hold:
self.cla()
q = mquiver.Quiver(self, *args, **kw)
self.add_collection(q, False)
self.update_datalim(q.XY)

self.add_collection(q, True)
self.autoscale_view()
return q
quiver.__doc__ = mquiver.Quiver.quiver_doc
Expand Down Expand Up @@ -6883,7 +6880,6 @@ def barbs(self, *args, **kw):
self.cla()
b = mquiver.Barbs(self, *args, **kw)
self.add_collection(b)
self.update_datalim(b.get_offsets())
self.autoscale_view()
return b

Expand Down
7 changes: 2 additions & 5 deletions lib/matplotlib/collections.py
Expand Up @@ -188,13 +188,13 @@ def get_datalim(self, transData):
# get_path_collection_extents handles nan but not masked arrays
offsets.shape = (-1, 2) # Make it Nx2

if paths:
if len(paths) and len(offsets):
result = mpath.get_path_collection_extents(
transform.frozen(), paths, self.get_transforms(),
offsets, transOffset.frozen())
result = result.inverse_transformed(transData)
else:
result = transforms.Bbox([[0, 0], [0, 0]])
result = transforms.Bbox.null()
return result

def get_window_extent(self, renderer):
Expand Down Expand Up @@ -1710,9 +1710,6 @@ def convert_mesh_to_triangles(self, meshWidth, meshHeight, coordinates):

return triangles, colors

def get_datalim(self, transData):
return self._bbox

@allow_rasterization
def draw(self, renderer):
if not self.get_visible():
Expand Down
9 changes: 9 additions & 0 deletions lib/matplotlib/quiver.py
Expand Up @@ -481,6 +481,15 @@ def _init(self):
sn = max(8, min(25, math.sqrt(self.N)))
self.width = 0.06 * self.span / sn

def get_datalim(self, transData):
trans = self.get_transform()
transOffset = self.get_offset_transform()
full_transform = (trans - transData) + (transOffset - transData)
XY = full_transform.transform(self.XY)
bbox = transforms.Bbox.null()
bbox.update_from_data_xy(XY, ignore=True)
return bbox

@allow_rasterization
def draw(self, renderer):
self._init()
Expand Down
4 changes: 1 addition & 3 deletions lib/matplotlib/streamplot.py
Expand Up @@ -168,9 +168,7 @@ def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None,
lc.set_cmap(cmap)
lc.set_norm(norm)
axes.add_collection(lc)

axes.update_datalim(((x.min(), y.min()), (x.max(), y.max())))
axes.autoscale_view(tight=True)
axes.autoscale_view()

ac = matplotlib.collections.PatchCollection(arrows)
stream_container = StreamplotSet(lc, ac)
Expand Down
Binary file modified lib/matplotlib/tests/baseline_images/test_pickle/multi_pickle.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 1 addition & 14 deletions lib/matplotlib/tests/test_axes.py
Expand Up @@ -58,20 +58,6 @@ def test_formatter_ticker():
ax.set_xlabel( "x-label 005" )
ax.autoscale_view()

@cleanup
def test_add_collection():
# Test if data limits are unchanged by adding an empty collection.
# Github issue #1490, pull #1497.
fig = matplotlib.figure.Figure()
fig2 = matplotlib.figure.Figure()
ax = fig.add_subplot(111)
ax2 = fig2.add_subplot(111)
coll = ax2.scatter([0, 1], [0, 1])
ax.add_collection(coll)
bounds = ax.dataLim.bounds
coll = ax2.scatter([], [])
ax.add_collection(coll)
assert ax.dataLim.bounds == bounds

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


@image_comparison(baseline_images=["twin_axis_locaters_formatters"])
def test_twin_axis_locaters_formatters():
vals = np.linspace(0, 1, num=5, endpoint=True)
Expand Down
51 changes: 49 additions & 2 deletions lib/matplotlib/tests/test_collections.py
Expand Up @@ -4,7 +4,7 @@

from nose.tools import assert_equal
import numpy as np
from numpy.testing import assert_array_equal
from numpy.testing import assert_array_equal, assert_array_almost_equal

import matplotlib.pyplot as plt
import matplotlib.collections as mcollections
Expand Down Expand Up @@ -396,9 +396,56 @@ def test_null_collection_datalim():
col = mcollections.PathCollection([])
col_data_lim = col.get_datalim(mtransforms.IdentityTransform())
assert_array_equal(col_data_lim.get_points(),
mtransforms.Bbox([[0, 0], [0, 0]]).get_points())
mtransforms.Bbox.null().get_points())


@cleanup
def test_add_collection():
# Test if data limits are unchanged by adding an empty collection.
# Github issue #1490, pull #1497.
ax = plt.axes()
plt.figure()
ax2 = plt.axes()
coll = ax2.scatter([0, 1], [0, 1])
ax.add_collection(coll)
bounds = ax.dataLim.bounds
coll = ax2.scatter([], [])
ax.add_collection(coll)
assert_equal(ax.dataLim.bounds, bounds)


@cleanup
def test_quiver_limits():
ax = plt.axes()
x, y = np.arange(8), np.arange(10)
data = u = v = np.linspace(0, 10, 80).reshape(10, 8)
q = plt.quiver(x, y, u, v)
assert_equal(q.get_datalim(ax.transData).bounds, (0., 0., 7., 9.))

plt.figure()
ax = plt.axes()
x = np.linspace(-5, 10, 20)
y = np.linspace(-2, 4, 10)
y, x = np.meshgrid(y, x)
trans = mtransforms.Affine2D().translate(25, 32) + ax.transData
plt.quiver(x, y, np.sin(x), np.cos(y), transform=trans)
assert_equal(ax.dataLim.bounds, (20.0, 30.0, 15.0, 6.0))


@cleanup
def test_barb_limits():
ax = plt.axes()
x = np.linspace(-5, 10, 20)
y = np.linspace(-2, 4, 10)
y, x = np.meshgrid(y, x)
trans = mtransforms.Affine2D().translate(25, 32) + ax.transData
plt.barbs(x, y, np.sin(x), np.cos(y), transform=trans)
# The calculated bounds are approximately the bounds of the original data,
# this is because the entire path is taken into account when updating the
# datalim.
assert_array_almost_equal(ax.dataLim.bounds, (20, 30, 15, 6),
decimal=2)

if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
8 changes: 6 additions & 2 deletions lib/matplotlib/tests/test_pickle.py
Expand Up @@ -155,10 +155,14 @@ def test_complete():
plt.subplot(3, 3, 5)
plt.pcolor(data)

plt.subplot(3, 3, 6)
ax = plt.subplot(3, 3, 6)
ax.set_xlim(0, 7)
ax.set_ylim(0, 9)
plt.streamplot(x, y, u, v)

plt.subplot(3, 3, 7)
ax = plt.subplot(3, 3, 7)
ax.set_xlim(0, 7)
ax.set_ylim(0, 9)
plt.quiver(x, y, u, v)

plt.subplot(3, 3, 8)
Expand Down
19 changes: 18 additions & 1 deletion lib/matplotlib/tests/test_streamplot.py
@@ -1,6 +1,8 @@
import numpy as np
from numpy.testing import assert_array_almost_equal
import matplotlib.pyplot as plt
from matplotlib.testing.decorators import image_comparison
from matplotlib.testing.decorators import image_comparison, cleanup
import matplotlib.transforms as mtransforms


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


@cleanup
def test_streamplot_limits():
ax = plt.axes()
x = np.linspace(-5, 10, 20)
y = np.linspace(-2, 4, 10)
y, x = np.meshgrid(y, x)
trans = mtransforms.Affine2D().translate(25, 32) + ax.transData
plt.barbs(x, y, np.sin(x), np.cos(y), transform=trans)
# The calculated bounds are approximately the bounds of the original data,
# this is because the entire path is taken into account when updating the
# datalim.
assert_array_almost_equal(ax.dataLim.bounds, (20, 30, 15, 6),
decimal=2)


if __name__=='__main__':
import nose
nose.runmodule()

0 comments on commit 169a2f6

Please sign in to comment.