Skip to content
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

AttributeError: 'Patch3DCollection' object has no attribute 'set_sizes' #2732

Merged
merged 2 commits into from Jan 29, 2014

Conversation

mdboom
Copy link
Member

@mdboom mdboom commented Jan 15, 2014

Hi,

I'm running into a bug with scatter3D in mplot3d when ran from python 3.3

I'm using the latest build from github (#e6f899338cb311ad80e89968271944fbdc7b7d7b)

Here is a minimal example:

import numpy as np
import matplotlib.pylab as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(np.arange(4), np.arange(4), zs=2)
plt.draw()

It fails with the following error:

AttributeError: 'Patch3DCollection' object has no attribute 'set_sizes'

> /home/guillaume/python3/lib/python3.3/site-packages/matplotlib-1.4.x-py3.3-linux-x86_64.egg/matplotlib/collections.py(728)draw()
    727     def draw(self, renderer):
--> 728         self.set_sizes(self._sizes, self.figure.dpi)
    729         Collection.draw(self, renderer)

Looks like the Patch3DCollection instance doesn't inherits properly from _CollectionWithSizes

Best,

Guillaume

@pelson
Copy link
Member

pelson commented Jan 15, 2014

Thanks @glyg - confirming this bug.

I was worried that this was a result of a PR which I merged recently, but it seems that this has been broken since July:

b8726d09026ba7507d8501de0fbd921ec2d1243e is the first bad commit
commit b8726d09026ba7507d8501de0fbd921ec2d1243e
Author: Michael Droettboom <@mdboom>
Date:   Mon Jul 22 13:38:18 2013 -0400

    Store transformations on collections as an Nx3x3 array, rather than a list of Transform objects.

    When the collection has the same styling and only varies by offsets, use draw_markers instead.

:040000 040000 4838686e8267fe2bf479aa7150d22d9609bb8671 f4709dcf72d8445cec5cafec50534a69e948617a M  lib
:040000 040000 e8864f5c97c9055c5a74750a2b93a98fd9c99d37 644434c8bfd2e140807fae6f82fb8806c0306e24 M  src

@mdboom - any ideas. Pinging @WeatherGod also.

@mdboom
Copy link
Member

mdboom commented Jan 15, 2014

mplot3d seems to do some funky things like changing the class of the Collection on the fly (as weird as that is, it's probably the best way available). Unfortunately, it seems to convert everything to a Patch3DCollection, regardless of the original class, and scatter has returned a PathCollection for a long time (even predating the commit @pelson identified), it just worked "by accident" because PathCollection and PatchCollection had the same methods.

I've attached a possible fix to this issue. It is not ready to merge, as it needs a test and some renaming of functions and updating of docstrings etc. but I want to run it through Travis to make sure it's a viable solution before proceeding further.

@@ -343,7 +343,7 @@ def do_3d_projection(self, renderer):
self._alpha = None
self.set_facecolors(zalpha(self._facecolor3d, vzs))
self.set_edgecolors(zalpha(self._edgecolor3d, vzs))
PatchCollection.set_offsets(self, list(zip(vxs, vys)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just looking at the github diffs, so don't have full context of the class, but this looks like it is in a method called do_3d_projection. In which case, can you not just call self.set_offsets?

@glyg
Copy link
Author

glyg commented Jan 17, 2014

Hi,

Just so you now, this PR fixes the issue for me, so thanks a lot!!

@mdboom
Copy link
Member

mdboom commented Jan 17, 2014

@WeatherGod: Does my suggested fix make sense to you?

@perimosocordiae
Copy link
Contributor

This PR fixes the initial issue for me as well, but I've also found a related issue for the same minimal example:

matplotlib/backends/backend_macosx.py in draw_path_collection(self, gc, master_transform, paths, all_transforms, offsets, offsetTrans, facecolors, edgecolors, linewidths, linestyles, antialiaseds, urls, offset_position)
     77             path_ids.append((path, transform))
     78         master_transform = master_transform.get_matrix()
---> 79         all_transforms = [t.get_matrix() for t in all_transforms]
     80         offsetTrans = offsetTrans.get_matrix()
     81         gc.draw_path_collection(master_transform, path_ids, all_transforms,

AttributeError: 'numpy.ndarray' object has no attribute 'get_matrix'

It's possible that this particular problem is specific to the OSX backend.
In any case, commenting out line 79 fixes it. (Apparently all_transforms is already a collection of numpy arrays.)

@mdboom
Copy link
Member

mdboom commented Jan 21, 2014

@perimosocordiae: Your suggested fix makes sense. I think the OS-X backend did not get updated when the transforms was changed to a single numpy array. I'm going to add it here.

mdboom added a commit that referenced this pull request Jan 29, 2014
AttributeError: 'Patch3DCollection' object has no attribute 'set_sizes'
@mdboom mdboom merged commit 9a164c7 into matplotlib:master Jan 29, 2014
@mdboom mdboom deleted the fix-patch3dcollection branch March 3, 2015 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants