Mplot3d questions

Hi Reinier,

Here are a number of issues in mplot3d that I would really like fixed, but can’t quite figure out. I would very much appreciate some feedback from you on these. (Where to start, what might be the cause, how hard is the fix…)

  • Global 3d object sorting. Not just for polygons, but all 3d objects like lines, and text as well. These objects have z values after all, so should be able to be placed in some sort of global z buffer.

  • When I implement ‘picking’ for bar3d plots, how can I know which bar was picked? In the picker callback, the event.artist is a Poly3DCollection object. I can call event.artist.get_paths() to get all the polygon paths, and determine which one the mouse click was in. But this data does not have any ‘z’ data. So, this will find 2 faces for the box you clicked. (You may get many more results from other boxes as well). And even with this data, I am unable to determine which box the path corresponds to. I can think of a few solutions:

  • Store some kind of data in Poly3DCollection corresponding to all path polygons, with the real world data so they can be matched up. (maybe this is already the case?)

  • make some kind of Bar3DPath class that inherits from Path which contains an extra data field to store the index of the bar the path belongs to. It should probably also store the real world coordinates and the screen z value as well.

  • override some pick event method and do this logic in the mplot3d code so that the user’s picker callback can simply use event.ind to get the bar index that was picked. just like the pick event for scatter().

  • picking does not seem to work for the 3D axis labels. The normal ‘picker=True’ parameter of set_xlabel(), set_ylabel() , and set_zlabel() does not seem to make the axis label pickable. Other 2d and 3d text on the plot is pickable however. It may be possible that the Axis3D object does not add the label to the Axes3D’s list of artists. Which means it doesn’t get searched for and found in Axes.__pick().

  • Is it possible to make 3d bars with transparent faces, so that they appear wireframe? I am pretty sure that patches support this, but I think the fancy face coloring bar3d does overrides the ‘none’ color specification.

  • How can I set axis tick label properties for 3D axes? This code does not work on Axes3D, but it works for normal 2D axes: setp(ax.get_xticklabels(), color=‘r’). Furthermore, there is no such ax.get_zticklabels(). Is there another way that this must be done? How can we support the setp(ax.get_zticklabels(), color=‘r’) paradigm?

Thanks!

-Ben

Ben Axelrod

Robotics Engineer

(800) 641-2676 x737

image002.gif

www.coroware.com

www.corobot.net

Hi,

I cannot answer your questions specifically but perhaps I can provide some insight. My current understanding is that most of mplot3d is a bit of a hack. I say this because I use it daily and I was the one who hacked it into a half working state out of necessity after it was originally fell out repair. Reiner finished the job in terms of returning it to its original usability.

Unfortunately, it still has many warts. Part of the problem is that matplotlib continues to evolve and add features that we have not added to mplot3d. I think that part of the reason this is happening is because it is not easily apparent what works and what does not. Indeed, the classes in mplot3d such as axes3d, axis3d, etc inherit from the mainline 2d classes axes, axis, etc. Thus it appears that methods have been implemented simply because the 3d objects have inherited them. This just gets worse as the 2d classes add more features. This causes a lot of frustration for users as sometimes these methods work by fluke and sometimes don’t. Even worse is that it is possible for an addition to some 2D code to call a method that has not been masked in the 3D object causing a breakage.

The reason this happened in the first place is that the original author realized that a lot of the 2d code could be reused to render a 2d view of the 3d space. I think that this reuse is a good idea but I think it would be much better if this was done more explicitly instead of using inheritance. In particular, I think that Axes3D should not inherit from Axes and simply contain an Axes object stored in self.axes. Then each method that is actually supported can be explicitly written and appropriately proxied to self.axes.method.

I have been thinking about trying to do a rewrite as I describe above for some time. I think that this would not only make it easier for users but would
make a much clearer code base in which it was more obvious how someone could
contribute. Alas, I have not found the time to do this, but perhaps in a month. :wink:

The other issue is that of speed. In the longer term, that can be addressed more easily. It will be a lot more work and more complicated but I am guessing that what needs to be done is a complete rewrite in something like OpenGL. That said, I am not sure how well this would work and if there are complications with ipython and threading, etc. I would be interested to know what people think about this.

I realize that I did not answer your questions except to provide some insight as to why mplot3d behaves oddly sometimes. Sorry :wink:

Best,
Jonathan.

···

On Thu, Feb 25, 2010 at 12:14 PM, Ben Axelrod <BAxelrod@…817…> wrote:

Hi Reinier,

Here are a number of issues in mplot3d that I would really like fixed, but can’t quite figure out. I would very much appreciate some feedback from you on these. (Where to start, what might be the cause, how hard is the fix…)

  • Global 3d object sorting. Not just for polygons, but all 3d objects like lines, and text as well. These objects have z values after all, so should be able to be placed in some sort of global z buffer.
  • When I implement ‘picking’ for bar3d plots, how can I know which bar was picked? In the picker callback, the event.artist is a Poly3DCollection object. I can call event.artist.get_paths() to get all the polygon paths, and determine which one the mouse click was in. But this data does not have any ‘z’ data. So, this will find 2 faces for the box you clicked. (You may get many more results from other boxes as well). And even with this data, I am unable to determine which box the path corresponds to. I can think of a few solutions:
  • Store some kind of data in Poly3DCollection corresponding to all path polygons, with the real world data so they can be matched up. (maybe this is already the case?)
  • make some kind of Bar3DPath class that inherits from Path which contains an extra data field to store the index of the bar the path belongs to. It should probably also store the real world coordinates and the screen z value as well.
  • override some pick event method and do this logic in the mplot3d code so that the user’s picker callback can simply use event.ind to get the bar index that was picked. just like the pick event for scatter().
  • picking does not seem to work for the 3D axis labels. The normal ‘picker=True’ parameter of set_xlabel(), set_ylabel() , and set_zlabel() does not seem to make the axis label pickable. Other 2d and 3d text on the plot is pickable however. It may be possible that the Axis3D object does not add the label to the Axes3D’s list of artists. Which means it doesn’t get searched for and found in Axes.__pick().
  • Is it possible to make 3d bars with transparent faces, so that they appear wireframe? I am pretty sure that patches support this, but I think the fancy face coloring bar3d does overrides the ‘none’ color specification.
  • How can I set axis tick label properties for 3D axes? This code does not work on Axes3D, but it works for normal 2D axes: setp(ax.get_xticklabels(), color=‘r’). Furthermore, there is no such ax.get_zticklabels(). Is there another way that this must be done? How can we support the setp(ax.get_zticklabels(), color=‘r’) paradigm?

Thanks!

-Ben

Ben Axelrod

Robotics Engineer

(800) 641-2676 x737

www.coroware.com

www.corobot.net


Download Intel® Parallel Studio Eval

Try the new software tools for yourself. Speed compiling, find bugs

proactively, and fine-tune applications for parallel performance.

See why Intel Parallel Studio got high marks during beta.

http://p.sf.net/sfu/intel-sw-dev


Matplotlib-devel mailing list

Matplotlib-devel@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Ben.

Sorry I did not see the other posts surrounding mplot3d or your patch. I am very excited to have that though. Thank you.

My opinion about a redesign still stands though.

Jon.

···

On Thu, Feb 25, 2010 at 11:16 PM, Jonathan Taylor <jtaylor@…756…> wrote:

Hi,

I cannot answer your questions specifically but perhaps I can provide some insight. My current understanding is that most of mplot3d is a bit of a hack. I say this because I use it daily and I was the one who hacked it into a half working state out of necessity after it was originally fell out repair. Reiner finished the job in terms of returning it to its original usability.

Unfortunately, it still has many warts. Part of the problem is that matplotlib continues to evolve and add features that we have not added to mplot3d. I think that part of the reason this is happening is because it is not easily apparent what works and what does not. Indeed, the classes in mplot3d such as axes3d, axis3d, etc inherit from the mainline 2d classes axes, axis, etc. Thus it appears that methods have been implemented simply because the 3d objects have inherited them. This just gets worse as the 2d classes add more features. This causes a lot of frustration for users as sometimes these methods work by fluke and sometimes don’t. Even worse is that it is possible for an addition to some 2D code to call a method that has not been masked in the 3D object causing a breakage.

The reason this happened in the first place is that the original author realized that a lot of the 2d code could be reused to render a 2d view of the 3d space. I think that this reuse is a good idea but I think it would be much better if this was done more explicitly instead of using inheritance. In particular, I think that Axes3D should not inherit from Axes and simply contain an Axes object stored in self.axes. Then each method that is actually supported can be explicitly written and appropriately proxied to self.axes.method.

I have been thinking about trying to do a rewrite as I describe above for some time. I think that this would not only make it easier for users but would
make a much clearer code base in which it was more obvious how someone could
contribute. Alas, I have not found the time to do this, but perhaps in a month. :wink:

The other issue is that of speed. In the longer term, that can be addressed more easily. It will be a lot more work and more complicated but I am guessing that what needs to be done is a complete rewrite in something like OpenGL. That said, I am not sure how well this would work and if there are complications with ipython and threading, etc. I would be interested to know what people think about this.

I realize that I did not answer your questions except to provide some insight as to why mplot3d behaves oddly sometimes. Sorry :wink:

Best,
Jonathan.

On Thu, Feb 25, 2010 at 12:14 PM, Ben Axelrod <BAxelrod@…817…> wrote:

Hi Reinier,

Here are a number of issues in mplot3d that I would really like fixed, but can’t quite figure out. I would very much appreciate some feedback from you on these. (Where to start, what might be the cause, how hard is the fix…)

  • Global 3d object sorting. Not just for polygons, but all 3d objects like lines, and text as well. These objects have z values after all, so should be able to be placed in some sort of global z buffer.
  • When I implement ‘picking’ for bar3d plots, how can I know which bar was picked? In the picker callback, the event.artist is a Poly3DCollection object. I can call event.artist.get_paths() to get all the polygon paths, and determine which one the mouse click was in. But this data does not have any ‘z’ data. So, this will find 2 faces for the box you clicked. (You may get many more results from other boxes as well). And even with this data, I am unable to determine which box the path corresponds to. I can think of a few solutions:
  • Store some kind of data in Poly3DCollection corresponding to all path polygons, with the real world data so they can be matched up. (maybe this is already the case?)
  • make some kind of Bar3DPath class that inherits from Path which contains an extra data field to store the index of the bar the path belongs to. It should probably also store the real world coordinates and the screen z value as well.
  • override some pick event method and do this logic in the mplot3d code so that the user’s picker callback can simply use event.ind to get the bar index that was picked. just like the pick event for scatter().
  • picking does not seem to work for the 3D axis labels. The normal ‘picker=True’ parameter of set_xlabel(), set_ylabel() , and set_zlabel() does not seem to make the axis label pickable. Other 2d and 3d text on the plot is pickable however. It may be possible that the Axis3D object does not add the label to the Axes3D’s list of artists. Which means it doesn’t get searched for and found in Axes.__pick().
  • Is it possible to make 3d bars with transparent faces, so that they appear wireframe? I am pretty sure that patches support this, but I think the fancy face coloring bar3d does overrides the ‘none’ color specification.
  • How can I set axis tick label properties for 3D axes? This code does not work on Axes3D, but it works for normal 2D axes: setp(ax.get_xticklabels(), color=‘r’). Furthermore, there is no such ax.get_zticklabels(). Is there another way that this must be done? How can we support the setp(ax.get_zticklabels(), color=‘r’) paradigm?

Thanks!

-Ben

Ben Axelrod

Robotics Engineer

(800) 641-2676 x737

www.coroware.com

www.corobot.net


Download Intel® Parallel Studio Eval

Try the new software tools for yourself. Speed compiling, find bugs

proactively, and fine-tune applications for parallel performance.

See why Intel Parallel Studio got high marks during beta.

http://p.sf.net/sfu/intel-sw-dev


Matplotlib-devel mailing list

Matplotlib-devel@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

If that may help the discussion, here are two links related to works I did on Python/OpenGL/scientific visualization and matplotlib:

glumpy: http://code.google.com/p/glumpy/
scigl: http://www.loria.fr/~rougier/coding/scigl/index.html

I also tried to write an OpenGL matplolib backend but it was not very convincing in terms of speed. This was the reason why I headed for glumpy. I think OpenGL may be a good framework for realtime visualization but is far from ideal to have paper quality output like the Agg backend. However, there exist a GL2PS (or pdf, svg, etc) library that may offer a very good compromise. Furthemore, there is no native way to display text even if FTGL is relatively widespread now.

Concerning threading and OpenGL, it might be a bit more complex than other backends since (from what I've understood), OpenGL requires to be in the main thread, this means no OpenGL call from other threads. I managed to implement an interactive console in glumpy using the GLUT system, and had some good experience with GTK as well but I don't know how it may work with qt or wx for example.

Nicolas

···

On Feb 26, 2010, at 05:16 , Jonathan Taylor wrote:

Hi,

I cannot answer your questions specifically but perhaps I can provide some insight. My current understanding is that most of mplot3d is a bit of a hack. I say this because I use it daily and I was the one who hacked it into a half working state out of necessity after it was originally fell out repair. Reiner finished the job in terms of returning it to its original usability.

Unfortunately, it still has many warts. Part of the problem is that matplotlib continues to evolve and add features that we have not added to mplot3d. I think that part of the reason this is happening is because it is not easily apparent what works and what does not. Indeed, the classes in mplot3d such as axes3d, axis3d, etc inherit from the mainline 2d classes axes, axis, etc. Thus it appears that methods have been implemented simply because the 3d objects have inherited them. This just gets worse as the 2d classes add more features. This causes a lot of frustration for users as sometimes these methods work by fluke and sometimes don't. Even worse is that it is possible for an addition to some 2D code to call a method that has not been masked in the 3D object causing a breakage.

The reason this happened in the first place is that the original author realized that a lot of the 2d code could be reused to render a 2d view of the 3d space. I think that this reuse is a good idea but I think it would be much better if this was done more explicitly instead of using inheritance. In particular, I think that Axes3D should not inherit from Axes and simply contain an Axes object stored in self.axes. Then each method that is actually supported can be explicitly written and appropriately proxied to self.axes.method.

I have been thinking about trying to do a rewrite as I describe above for some time. I think that this would not only make it easier for users but would make a much clearer code base in which it was more obvious how someone could contribute. Alas, I have not found the time to do this, but perhaps in a month. :wink:

The other issue is that of speed. In the longer term, that can be addressed more easily. It will be a lot more work and more complicated but I am guessing that what needs to be done is a complete rewrite in something like OpenGL. That said, I am not sure how well this would work and if there are complications with ipython and threading, etc. I would be interested to know what people think about this.

I realize that I did not answer your questions except to provide some insight as to why mplot3d behaves oddly sometimes. Sorry :wink:

Best,
Jonathan.

On Thu, Feb 25, 2010 at 12:14 PM, Ben Axelrod <BAxelrod@...817...> wrote:
Hi Reinier,

Here are a number of issues in mplot3d that I would really like fixed, but can't quite figure out. I would very much appreciate some feedback from you on these. (Where to start, what might be the cause, how hard is the fix...)

* Global 3d object sorting. Not just for polygons, but all 3d objects like lines, and text as well. These objects have z values after all, so should be able to be placed in some sort of global z buffer.

* When I implement 'picking' for bar3d plots, how can I know which bar was picked? In the picker callback, the event.artist is a Poly3DCollection object. I can call event.artist.get_paths() to get all the polygon paths, and determine which one the mouse click was in. But this data does not have any 'z' data. So, this will find 2 faces for the box you clicked. (You may get many more results from other boxes as well). And even with this data, I am unable to determine which box the path corresponds to. I can think of a few solutions:
  - Store some kind of data in Poly3DCollection corresponding to all path polygons, *with* the real world data so they can be matched up. (maybe this is already the case?)
  - make some kind of Bar3DPath class that inherits from Path which contains an extra data field to store the index of the bar the path belongs to. It should probably also store the real world coordinates and the screen z value as well.
- override some pick event method and do this logic in the mplot3d code so that the user's picker callback can simply use event.ind to get the bar index that was picked. just like the pick event for scatter().

* picking does not seem to work for the 3D axis labels. The normal 'picker=True' parameter of set_xlabel(), set_ylabel() , and set_zlabel() does not seem to make the axis label pickable. Other 2d and 3d text on the plot is pickable however. It may be possible that the Axis3D object does not add the label to the Axes3D's list of artists. Which means it doesn't get searched for and found in Axes.__pick().

* Is it possible to make 3d bars with transparent faces, so that they appear wireframe? I am pretty sure that patches support this, but I think the fancy face coloring bar3d does overrides the 'none' color specification.

* How can I set axis tick label properties for 3D axes? This code does not work on Axes3D, but it works for normal 2D axes: setp(ax.get_xticklabels(), color='r'). Furthermore, there is no such ax.get_zticklabels(). Is there another way that this must be done? How can we support the setp(ax.get_zticklabels(), color='r') paradigm?

Thanks!
-Ben

Ben Axelrod
Robotics Engineer
(800) 641-2676 x737

www.coroware.com
www.corobot.net

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel