matplotlib 3d scatter plot in Traits

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

matplotlib 3d scatter plot in Traits

Brennan Williams
Just a quick question to see if anyone has plotted a mplot3d scatter
plot inside a Traits dialog?

Brennan
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: matplotlib 3d scatter plot in Traits

Jaidev Deshpande
On Mon, Jun 11, 2012 at 10:39 PM, Brennan Williams
<[hidden email]> wrote:
> Just a quick question to see if anyone has plotted a mplot3d scatter
> plot inside a Traits dialog?
>
> Brennan
> _______________________________________________
> Enthought-Dev mailing list
> [hidden email]
> https://mail.enthought.com/mailman/listinfo/enthought-dev

Hi,

I'm not sure if anyone has done it. But it's definitely doable. Any
matplotlib plot can be put inside a traits view but it needs a
separate editor. Please refer to this
-http://gael-varoquaux.info/computers/traits_tutorial/traits_tutorial.html#making-a-traits-editor-from-a-matplotlib-plot
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: matplotlib 3d scatter plot in Traits

Brennan Williams
Got it going ok and yes I did a bit of a cut and paste of Gael's example
code.
I get a 3D scatter plot but I don't have the interactive zoom/pan
controls working but I suppose that is hardly surprising as they are
matplotlib GUI interactions rather than Traits GUI interactions.

Brennan

On 11/06/2012 7:07 p.m., Jaidev Deshpande wrote:

> On Mon, Jun 11, 2012 at 10:39 PM, Brennan Williams
> <[hidden email]>  wrote:
>> Just a quick question to see if anyone has plotted a mplot3d scatter
>> plot inside a Traits dialog?
>>
>> Brennan
>> _______________________________________________
>> Enthought-Dev mailing list
>> [hidden email]
>> https://mail.enthought.com/mailman/listinfo/enthought-dev
> Hi,
>
> I'm not sure if anyone has done it. But it's definitely doable. Any
> matplotlib plot can be put inside a traits view but it needs a
> separate editor. Please refer to this
> -http://gael-varoquaux.info/computers/traits_tutorial/traits_tutorial.html#making-a-traits-editor-from-a-matplotlib-plot
> _______________________________________________
> Enthought-Dev mailing list
> [hidden email]
> https://mail.enthought.com/mailman/listinfo/enthought-dev
>

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: matplotlib 3d scatter plot in Traits

Jaidev Deshpande
Hi,

> I get a 3D scatter plot but I don't have the interactive zoom/pan
> controls working but I suppose that is hardly surprising as they are
> matplotlib GUI interactions rather than Traits GUI interactions.

It is indeed possible to get the matplotlib zoom and pan operations
into the dialog. Out of curiosity, which part of the MPLFigureEditor
did you use?

Thanks
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: matplotlib 3d scatter plot in Traits

Brennan Williams
On 11/06/2012 10:16 p.m., Jaidev Deshpande wrote:
> Hi,
>
>> I get a 3D scatter plot but I don't have the interactive zoom/pan
>> controls working but I suppose that is hardly surprising as they are
>> matplotlib GUI interactions rather than Traits GUI interactions.
> It is indeed possible to get the matplotlib zoom and pan operations
> into the dialog. Out of curiosity, which part of the MPLFigureEditor
> did you use?

My code.....


import matplotlib.pyplot as mplplt
from mpl_figure_editor import MPLFigureEditor
from matplotlib.figure import Figure
from mpl_toolkits.mplot3d import Axes3D

....
     def create_plot(self):
         ....
         self.figure=mplplt.figure()
         ax = self.figure.add_subplot(111, projection='3d')
         .....
         ax.scatter(xarray, yarray, zarray, c='b', marker='o')

         ax.set_xlabel(xvar.name)
         ax.set_ylabel(yvar.name)
         ax.set_zlabel(self.name)

         mplplt.ion()


where my mpl_figure_editor is a direct copy of that from Gael's
document....namely....

import wx

import matplotlib
# We want matplotlib to use a wxPython backend
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as
FigureCanvas
from matplotlib.figure import Figure
from matplotlib.backends.backend_wx import NavigationToolbar2Wx

from enthought.traits.api import Any, Instance
from enthought.traits.ui.wx.editor import Editor
from enthought.traits.ui.wx.basic_editor_factory import BasicEditorFactory

class _MPLFigureEditor(Editor):

     scrollable  = True

     def init(self, parent):
         self.control = self._create_canvas(parent)
         self.set_tooltip()

     def update_editor(self):
         pass

     def _create_canvas(self, parent):
         """ Create the MPL canvas. """
         # The panel lets us add additional controls.
         panel = wx.Panel(parent, -1, style=wx.CLIP_CHILDREN)
         sizer = wx.BoxSizer(wx.VERTICAL)
         panel.SetSizer(sizer)
         # matplotlib commands to create a canvas
         mpl_control = FigureCanvas(panel, -1, self.value)
         sizer.Add(mpl_control, 1, wx.LEFT | wx.TOP | wx.GROW)
         toolbar = NavigationToolbar2Wx(mpl_control)
         sizer.Add(toolbar, 0, wx.EXPAND)
         self.value.canvas.SetMinSize((10,10))
         return panel

class MPLFigureEditor(BasicEditorFactory):

     klass = _MPLFigureEditor


if __name__ == "__main__":
     # Create a window to demo the editor
     from enthought.traits.api import HasTraits
     from enthought.traits.ui.api import View, Item
     from numpy import sin, cos, linspace, pi

     class Test(HasTraits):

         figure = Instance(Figure, ())

         view = View(Item('figure', editor=MPLFigureEditor(),
                                 show_label=False),
                         width=400,
                         height=300,
                         resizable=True)

         def __init__(self):
             super(Test, self).__init__()
             axes = self.figure.add_subplot(111)
             t = linspace(0, 2*pi, 200)
             axes.plot(sin(t)*(1+0.5*cos(11*t)), cos(t)*(1+0.5*cos(11*t)))

     Test().configure_traits()




> Thanks
> _______________________________________________
> Enthought-Dev mailing list
> [hidden email]
> https://mail.enthought.com/mailman/listinfo/enthought-dev
>

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: matplotlib 3d scatter plot in Traits

Brennan Williams
Got the zoom working. I was overwriting my 'figure' which led to the
zoom/rotate controls not working.

I just need to work out how to colour code my circles on my scatter plot
now. They are all one colour. But that is a matplotlib question, not a
Traits one.

Thanks to Gael for his work on this.

Brennan

On 11/06/2012 10:51 p.m., Brennan Williams wrote:

> On 11/06/2012 10:16 p.m., Jaidev Deshpande wrote:
>> Hi,
>>
>>> I get a 3D scatter plot but I don't have the interactive zoom/pan
>>> controls working but I suppose that is hardly surprising as they are
>>> matplotlib GUI interactions rather than Traits GUI interactions.
>> It is indeed possible to get the matplotlib zoom and pan operations
>> into the dialog. Out of curiosity, which part of the MPLFigureEditor
>> did you use?
> My code.....
>
>
> import matplotlib.pyplot as mplplt
> from mpl_figure_editor import MPLFigureEditor
> from matplotlib.figure import Figure
> from mpl_toolkits.mplot3d import Axes3D
>
> ....
>       def create_plot(self):
>           ....
>           self.figure=mplplt.figure()
>           ax = self.figure.add_subplot(111, projection='3d')
>           .....
>           ax.scatter(xarray, yarray, zarray, c='b', marker='o')
>
>           ax.set_xlabel(xvar.name)
>           ax.set_ylabel(yvar.name)
>           ax.set_zlabel(self.name)
>
>           mplplt.ion()
>
>
> where my mpl_figure_editor is a direct copy of that from Gael's
> document....namely....
>
> import wx
>
> import matplotlib
> # We want matplotlib to use a wxPython backend
> matplotlib.use('WXAgg')
> from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as
> FigureCanvas
> from matplotlib.figure import Figure
> from matplotlib.backends.backend_wx import NavigationToolbar2Wx
>
> from enthought.traits.api import Any, Instance
> from enthought.traits.ui.wx.editor import Editor
> from enthought.traits.ui.wx.basic_editor_factory import BasicEditorFactory
>
> class _MPLFigureEditor(Editor):
>
>       scrollable  = True
>
>       def init(self, parent):
>           self.control = self._create_canvas(parent)
>           self.set_tooltip()
>
>       def update_editor(self):
>           pass
>
>       def _create_canvas(self, parent):
>           """ Create the MPL canvas. """
>           # The panel lets us add additional controls.
>           panel = wx.Panel(parent, -1, style=wx.CLIP_CHILDREN)
>           sizer = wx.BoxSizer(wx.VERTICAL)
>           panel.SetSizer(sizer)
>           # matplotlib commands to create a canvas
>           mpl_control = FigureCanvas(panel, -1, self.value)
>           sizer.Add(mpl_control, 1, wx.LEFT | wx.TOP | wx.GROW)
>           toolbar = NavigationToolbar2Wx(mpl_control)
>           sizer.Add(toolbar, 0, wx.EXPAND)
>           self.value.canvas.SetMinSize((10,10))
>           return panel
>
> class MPLFigureEditor(BasicEditorFactory):
>
>       klass = _MPLFigureEditor
>
>
> if __name__ == "__main__":
>       # Create a window to demo the editor
>       from enthought.traits.api import HasTraits
>       from enthought.traits.ui.api import View, Item
>       from numpy import sin, cos, linspace, pi
>
>       class Test(HasTraits):
>
>           figure = Instance(Figure, ())
>
>           view = View(Item('figure', editor=MPLFigureEditor(),
>                                   show_label=False),
>                           width=400,
>                           height=300,
>                           resizable=True)
>
>           def __init__(self):
>               super(Test, self).__init__()
>               axes = self.figure.add_subplot(111)
>               t = linspace(0, 2*pi, 200)
>               axes.plot(sin(t)*(1+0.5*cos(11*t)), cos(t)*(1+0.5*cos(11*t)))
>
>       Test().configure_traits()
>
>
>
>
>> Thanks
>> _______________________________________________
>> Enthought-Dev mailing list
>> [hidden email]
>> https://mail.enthought.com/mailman/listinfo/enthought-dev
>>
> _______________________________________________
> Enthought-Dev mailing list
> [hidden email]
> https://mail.enthought.com/mailman/listinfo/enthought-dev
>

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: matplotlib 3d scatter plot in Traits

Jaidev Deshpande
On Tue, Jun 12, 2012 at 3:58 AM, Brennan Williams
<[hidden email]> wrote:

> Got the zoom working. I was overwriting my 'figure' which led to the
> zoom/rotate controls not working.
>
> I just need to work out how to colour code my circles on my scatter plot
> now. They are all one colour. But that is a matplotlib question, not a
> Traits one.
>
> Thanks to Gael for his work on this.
>
> Brennan
>
> On 11/06/2012 10:51 p.m., Brennan Williams wrote:
>> On 11/06/2012 10:16 p.m., Jaidev Deshpande wrote:
>>> Hi,
>>>
>>>> I get a 3D scatter plot but I don't have the interactive zoom/pan
>>>> controls working but I suppose that is hardly surprising as they are
>>>> matplotlib GUI interactions rather than Traits GUI interactions.
>>> It is indeed possible to get the matplotlib zoom and pan operations
>>> into the dialog. Out of curiosity, which part of the MPLFigureEditor
>>> did you use?
>> My code.....
>>
>>
>> import matplotlib.pyplot as mplplt
>> from mpl_figure_editor import MPLFigureEditor
>> from matplotlib.figure import Figure
>> from mpl_toolkits.mplot3d import Axes3D
>>
>> ....
>>       def create_plot(self):
>>           ....
>>           self.figure=mplplt.figure()
>>           ax = self.figure.add_subplot(111, projection='3d')
>>           .....
>>           ax.scatter(xarray, yarray, zarray, c='b', marker='o')
>>
>>           ax.set_xlabel(xvar.name)
>>           ax.set_ylabel(yvar.name)
>>           ax.set_zlabel(self.name)
>>
>>           mplplt.ion()
>>
>>
>> where my mpl_figure_editor is a direct copy of that from Gael's
>> document....namely....
>>
>> import wx
>>
>> import matplotlib
>> # We want matplotlib to use a wxPython backend
>> matplotlib.use('WXAgg')
>> from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as
>> FigureCanvas
>> from matplotlib.figure import Figure
>> from matplotlib.backends.backend_wx import NavigationToolbar2Wx
>>
>> from enthought.traits.api import Any, Instance
>> from enthought.traits.ui.wx.editor import Editor
>> from enthought.traits.ui.wx.basic_editor_factory import BasicEditorFactory
>>
>> class _MPLFigureEditor(Editor):
>>
>>       scrollable  = True
>>
>>       def init(self, parent):
>>           self.control = self._create_canvas(parent)
>>           self.set_tooltip()
>>
>>       def update_editor(self):
>>           pass
>>
>>       def _create_canvas(self, parent):
>>           """ Create the MPL canvas. """
>>           # The panel lets us add additional controls.
>>           panel = wx.Panel(parent, -1, style=wx.CLIP_CHILDREN)
>>           sizer = wx.BoxSizer(wx.VERTICAL)
>>           panel.SetSizer(sizer)
>>           # matplotlib commands to create a canvas
>>           mpl_control = FigureCanvas(panel, -1, self.value)
>>           sizer.Add(mpl_control, 1, wx.LEFT | wx.TOP | wx.GROW)
>>           toolbar = NavigationToolbar2Wx(mpl_control)
>>           sizer.Add(toolbar, 0, wx.EXPAND)
>>           self.value.canvas.SetMinSize((10,10))
>>           return panel
>>
>> class MPLFigureEditor(BasicEditorFactory):
>>
>>       klass = _MPLFigureEditor
>>
>>
>> if __name__ == "__main__":
>>       # Create a window to demo the editor
>>       from enthought.traits.api import HasTraits
>>       from enthought.traits.ui.api import View, Item
>>       from numpy import sin, cos, linspace, pi
>>
>>       class Test(HasTraits):
>>
>>           figure = Instance(Figure, ())
>>
>>           view = View(Item('figure', editor=MPLFigureEditor(),
>>                                   show_label=False),
>>                           width=400,
>>                           height=300,
>>                           resizable=True)
>>
>>           def __init__(self):
>>               super(Test, self).__init__()
>>               axes = self.figure.add_subplot(111)
>>               t = linspace(0, 2*pi, 200)
>>               axes.plot(sin(t)*(1+0.5*cos(11*t)), cos(t)*(1+0.5*cos(11*t)))
>>
>>       Test().configure_traits()
>>
>>
>>
>>
>>> Thanks
>>> _______________________________________________
>>> Enthought-Dev mailing list
>>> [hidden email]
>>> https://mail.enthought.com/mailman/listinfo/enthought-dev
>>>
>> _______________________________________________
>> Enthought-Dev mailing list
>> [hidden email]
>> https://mail.enthought.com/mailman/listinfo/enthought-dev
>>
>
> _______________________________________________
> Enthought-Dev mailing list
> [hidden email]
> https://mail.enthought.com/mailman/listinfo/enthought-dev


Tried the following with the MPLEditor, the mpl plot on the left half
of the widget and a very silly looking text field on the right (just
because I had to do something on the right). And I noticed that the
toolbars are already coded into the editor, in the file
mpl_figure_editor.py. Pans and zooms fine. Are you clustering the
data, by any chance?

from mpl_figure_editor import MPLFigureEditor
from matplotlib.figure import Figure
from traits.api import HasTraits, Instance, Str, Int
from traitsui.api import View, Item, Group, HSplit
import random

class ScatterPlot(HasTraits):

    scatterplot = Instance(Figure,())
    name = Str
    traits_view = View(HSplit(Item('scatterplot', editor = MPLFigureEditor()),
                              Item('name'), show_labels = False),
                              resizable = True)

    def __init__(self):
        # some random scatterplot data
        a = map(lambda x: random.randint(1,10), range(20))
        b = map(lambda x: random.randint(1,10), range(20))

        axes = self.scatterplot.add_subplot(111)
        axes.plot(a,b, 'ro')


if __name__=='__main__':
    ScatterPlot().configure_traits()

Cheers
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: matplotlib 3d scatter plot in Traits

Gael Varoquaux
In reply to this post by Brennan Williams
On Mon, Jun 11, 2012 at 11:28:50PM +0100, Brennan Williams wrote:
> Thanks to Gael for his work on this.

Scanning my mail quickly, I just saw that (one is primed to his name :$).

Thanks for you thanks :). It's a pleasure to see that this code is still
available.

G
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: matplotlib 3d scatter plot in Traits

Gael Varoquaux
On Tue, Jun 12, 2012 at 02:30:57AM +0200, Gael Varoquaux wrote:
> Thanks for you thanks :). It's a pleasure to see that this code is still
> available.

 ^usefull, I meant.
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: matplotlib 3d scatter plot in Traits

Brennan Williams
In reply to this post by Brennan Williams
Just another question about how Traits wraps around matplotlib...

I use a Treeeditor so quite often my application comes out of one view
to display another in the rhs pane.

I'm using...

from matplotlib.figure import Figure
from mpl_toolkits.mplot3d import Axes3D

and in my RZThing class definition I have...

figure=Instance(Figure)
axes3d=Instance(Axes3D)

and then in my class method to create the plot I go

self.figure=mplplt.figure()
self.axes3d = self.figure.add_subplot(111, projection='3d')

This works ok the first time.

But if I go to another RZThing object in my tree (which creates a view
for that instance of RZThing) and then come back to my original RZThing
I get error messages such as....

  File "c:\program files\rezen27\rz_traits.py", line ..., in rebuildPlot2a
     self.axes3d = self.figure.add_subplot(111, projection='3d')
   File "c:\python27\lib\site-packages\matplotlib\figure.py", line 777,
in add_subplot
     a = subplot_class_factory(projection_class)(self, *args, **kwargs)
   File "c:\python27\lib\site-packages\matplotlib\axes.py", line 8372,
in __init__
     self._axes_class.__init__(self, fig, self.figbox, **kwargs)
   File "c:\python27\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py",
line 98, in __init__
     self.mouse_init()
   File "c:\python27\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py",
line 798, in mouse_init
     c1 = canv.mpl_connect('motion_notify_event', self._on_move)
   File "c:\python27\lib\site-packages\wx\_core.py", line 14568, in
__getattr__
     raise PyDeadObjectError(self.attrStr % self._name)
PyDeadObjectError: The C++ part of the FigureCanvasWxAgg object has been
deleted, attribute access no longer allowed.

It looks perhaps like I'm losing self.figure somewhere.
Given that Figure and Axes3D are matplotlib objects and not HasTraits
objects, am I using them correctly?
Am I perhaps creating them as class attributes rather than instance
attributes?

Any ideas?

Brennan


On 11/06/2012 10:51 p.m., Brennan Williams wrote:

> On 11/06/2012 10:16 p.m., Jaidev Deshpande wrote:
>> Hi,
>>
>>> I get a 3D scatter plot but I don't have the interactive zoom/pan
>>> controls working but I suppose that is hardly surprising as they are
>>> matplotlib GUI interactions rather than Traits GUI interactions.
>> It is indeed possible to get the matplotlib zoom and pan operations
>> into the dialog. Out of curiosity, which part of the MPLFigureEditor
>> did you use?
> My code.....
>
>
> import matplotlib.pyplot as mplplt
> from mpl_figure_editor import MPLFigureEditor
> from matplotlib.figure import Figure
> from mpl_toolkits.mplot3d import Axes3D
>
> ....
>       def create_plot(self):
>           ....
>           self.figure=mplplt.figure()
>           ax = self.figure.add_subplot(111, projection='3d')
>           .....
>           ax.scatter(xarray, yarray, zarray, c='b', marker='o')
>
>           ax.set_xlabel(xvar.name)
>           ax.set_ylabel(yvar.name)
>           ax.set_zlabel(self.name)
>
>           mplplt.ion()
>
>
> where my mpl_figure_editor is a direct copy of that from Gael's
> document....namely....
>
> import wx
>
> import matplotlib
> # We want matplotlib to use a wxPython backend
> matplotlib.use('WXAgg')
> from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as
> FigureCanvas
> from matplotlib.figure import Figure
> from matplotlib.backends.backend_wx import NavigationToolbar2Wx
>
> from enthought.traits.api import Any, Instance
> from enthought.traits.ui.wx.editor import Editor
> from enthought.traits.ui.wx.basic_editor_factory import BasicEditorFactory
>
> class _MPLFigureEditor(Editor):
>
>       scrollable  = True
>
>       def init(self, parent):
>           self.control = self._create_canvas(parent)
>           self.set_tooltip()
>
>       def update_editor(self):
>           pass
>
>       def _create_canvas(self, parent):
>           """ Create the MPL canvas. """
>           # The panel lets us add additional controls.
>           panel = wx.Panel(parent, -1, style=wx.CLIP_CHILDREN)
>           sizer = wx.BoxSizer(wx.VERTICAL)
>           panel.SetSizer(sizer)
>           # matplotlib commands to create a canvas
>           mpl_control = FigureCanvas(panel, -1, self.value)
>           sizer.Add(mpl_control, 1, wx.LEFT | wx.TOP | wx.GROW)
>           toolbar = NavigationToolbar2Wx(mpl_control)
>           sizer.Add(toolbar, 0, wx.EXPAND)
>           self.value.canvas.SetMinSize((10,10))
>           return panel
>
> class MPLFigureEditor(BasicEditorFactory):
>
>       klass = _MPLFigureEditor
>
>
> if __name__ == "__main__":
>       # Create a window to demo the editor
>       from enthought.traits.api import HasTraits
>       from enthought.traits.ui.api import View, Item
>       from numpy import sin, cos, linspace, pi
>
>       class Test(HasTraits):
>
>           figure = Instance(Figure, ())
>
>           view = View(Item('figure', editor=MPLFigureEditor(),
>                                   show_label=False),
>                           width=400,
>                           height=300,
>                           resizable=True)
>
>           def __init__(self):
>               super(Test, self).__init__()
>               axes = self.figure.add_subplot(111)
>               t = linspace(0, 2*pi, 200)
>               axes.plot(sin(t)*(1+0.5*cos(11*t)), cos(t)*(1+0.5*cos(11*t)))
>
>       Test().configure_traits()
>
>
>
>
>> Thanks
>> _______________________________________________
>> Enthought-Dev mailing list
>> [hidden email]
>> https://mail.enthought.com/mailman/listinfo/enthought-dev
>>
> _______________________________________________
> Enthought-Dev mailing list
> [hidden email]
> https://mail.enthought.com/mailman/listinfo/enthought-dev
>

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: matplotlib 3d scatter plot in Traits

Brennan Williams
When I embed a matplotlib 3D scatter plot in my Traits app I can rotate,
zoom etc but I don't get the x,y,z positional info down below the plot
(and below the matplotlib buttons).
You do get that when running a standalone matplotlib script. But in
Traits that part of the window/plot is not displayed. Anyone have an
idea whether this is a Traits or a matplotlib issue?

Brennan

On 12/06/2012 10:44 a.m., Brennan Williams wrote:

> Just another question about how Traits wraps around matplotlib...
>
> I use a Treeeditor so quite often my application comes out of one view
> to display another in the rhs pane.
>
> I'm using...
>
> from matplotlib.figure import Figure
> from mpl_toolkits.mplot3d import Axes3D
>
> and in my RZThing class definition I have...
>
> figure=Instance(Figure)
> axes3d=Instance(Axes3D)
>
> and then in my class method to create the plot I go
>
> self.figure=mplplt.figure()
> self.axes3d = self.figure.add_subplot(111, projection='3d')
>
> This works ok the first time.
>
> But if I go to another RZThing object in my tree (which creates a view
> for that instance of RZThing) and then come back to my original RZThing
> I get error messages such as....
>
>    File "c:\program files\rezen27\rz_traits.py", line ..., in rebuildPlot2a
>       self.axes3d = self.figure.add_subplot(111, projection='3d')
>     File "c:\python27\lib\site-packages\matplotlib\figure.py", line 777,
> in add_subplot
>       a = subplot_class_factory(projection_class)(self, *args, **kwargs)
>     File "c:\python27\lib\site-packages\matplotlib\axes.py", line 8372,
> in __init__
>       self._axes_class.__init__(self, fig, self.figbox, **kwargs)
>     File "c:\python27\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py",
> line 98, in __init__
>       self.mouse_init()
>     File "c:\python27\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py",
> line 798, in mouse_init
>       c1 = canv.mpl_connect('motion_notify_event', self._on_move)
>     File "c:\python27\lib\site-packages\wx\_core.py", line 14568, in
> __getattr__
>       raise PyDeadObjectError(self.attrStr % self._name)
> PyDeadObjectError: The C++ part of the FigureCanvasWxAgg object has been
> deleted, attribute access no longer allowed.
>
> It looks perhaps like I'm losing self.figure somewhere.
> Given that Figure and Axes3D are matplotlib objects and not HasTraits
> objects, am I using them correctly?
> Am I perhaps creating them as class attributes rather than instance
> attributes?
>
> Any ideas?
>
> Brennan
>
>
> On 11/06/2012 10:51 p.m., Brennan Williams wrote:
>> On 11/06/2012 10:16 p.m., Jaidev Deshpande wrote:
>>> Hi,
>>>
>>>> I get a 3D scatter plot but I don't have the interactive zoom/pan
>>>> controls working but I suppose that is hardly surprising as they are
>>>> matplotlib GUI interactions rather than Traits GUI interactions.
>>> It is indeed possible to get the matplotlib zoom and pan operations
>>> into the dialog. Out of curiosity, which part of the MPLFigureEditor
>>> did you use?
>> My code.....
>>
>>
>> import matplotlib.pyplot as mplplt
>> from mpl_figure_editor import MPLFigureEditor
>> from matplotlib.figure import Figure
>> from mpl_toolkits.mplot3d import Axes3D
>>
>> ....
>>        def create_plot(self):
>>            ....
>>            self.figure=mplplt.figure()
>>            ax = self.figure.add_subplot(111, projection='3d')
>>            .....
>>            ax.scatter(xarray, yarray, zarray, c='b', marker='o')
>>
>>            ax.set_xlabel(xvar.name)
>>            ax.set_ylabel(yvar.name)
>>            ax.set_zlabel(self.name)
>>
>>            mplplt.ion()
>>
>>
>> where my mpl_figure_editor is a direct copy of that from Gael's
>> document....namely....
>>
>> import wx
>>
>> import matplotlib
>> # We want matplotlib to use a wxPython backend
>> matplotlib.use('WXAgg')
>> from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as
>> FigureCanvas
>> from matplotlib.figure import Figure
>> from matplotlib.backends.backend_wx import NavigationToolbar2Wx
>>
>> from enthought.traits.api import Any, Instance
>> from enthought.traits.ui.wx.editor import Editor
>> from enthought.traits.ui.wx.basic_editor_factory import BasicEditorFactory
>>
>> class _MPLFigureEditor(Editor):
>>
>>        scrollable  = True
>>
>>        def init(self, parent):
>>            self.control = self._create_canvas(parent)
>>            self.set_tooltip()
>>
>>        def update_editor(self):
>>            pass
>>
>>        def _create_canvas(self, parent):
>>            """ Create the MPL canvas. """
>>            # The panel lets us add additional controls.
>>            panel = wx.Panel(parent, -1, style=wx.CLIP_CHILDREN)
>>            sizer = wx.BoxSizer(wx.VERTICAL)
>>            panel.SetSizer(sizer)
>>            # matplotlib commands to create a canvas
>>            mpl_control = FigureCanvas(panel, -1, self.value)
>>            sizer.Add(mpl_control, 1, wx.LEFT | wx.TOP | wx.GROW)
>>            toolbar = NavigationToolbar2Wx(mpl_control)
>>            sizer.Add(toolbar, 0, wx.EXPAND)
>>            self.value.canvas.SetMinSize((10,10))
>>            return panel
>>
>> class MPLFigureEditor(BasicEditorFactory):
>>
>>        klass = _MPLFigureEditor
>>
>>
>> if __name__ == "__main__":
>>        # Create a window to demo the editor
>>        from enthought.traits.api import HasTraits
>>        from enthought.traits.ui.api import View, Item
>>        from numpy import sin, cos, linspace, pi
>>
>>        class Test(HasTraits):
>>
>>            figure = Instance(Figure, ())
>>
>>            view = View(Item('figure', editor=MPLFigureEditor(),
>>                                    show_label=False),
>>                            width=400,
>>                            height=300,
>>                            resizable=True)
>>
>>            def __init__(self):
>>                super(Test, self).__init__()
>>                axes = self.figure.add_subplot(111)
>>                t = linspace(0, 2*pi, 200)
>>                axes.plot(sin(t)*(1+0.5*cos(11*t)), cos(t)*(1+0.5*cos(11*t)))
>>
>>        Test().configure_traits()
>>
>>
>>
>>
>>> Thanks
>>> _______________________________________________
>>> Enthought-Dev mailing list
>>> [hidden email]
>>> https://mail.enthought.com/mailman/listinfo/enthought-dev
>>>
>> _______________________________________________
>> Enthought-Dev mailing list
>> [hidden email]
>> https://mail.enthought.com/mailman/listinfo/enthought-dev
>>
> _______________________________________________
> Enthought-Dev mailing list
> [hidden email]
> https://mail.enthought.com/mailman/listinfo/enthought-dev
>

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: matplotlib 3d scatter plot in Traits

Robert Kern
On Tue, Jun 19, 2012 at 10:30 AM, Brennan Williams
<[hidden email]> wrote:
> When I embed a matplotlib 3D scatter plot in my Traits app I can rotate,
> zoom etc but I don't get the x,y,z positional info down below the plot
> (and below the matplotlib buttons).
> You do get that when running a standalone matplotlib script. But in
> Traits that part of the window/plot is not displayed. Anyone have an
> idea whether this is a Traits or a matplotlib issue?

The x,y,z positional information is in a status bar. Status bars are
part of the decoration of full-blown windows, not embedded widgets.
When you embed a matplotlib plot inside of a Traits UI, you are just
embedding the plain plot widget. If you know how to get this
information out of the matplotlib plot widget, then you can push it
into a Traits UI StatusBar:

  https://github.com/enthought/traitsui/blob/master/examples/demo/Advanced/Statusbar_demo.py

Or just a "readonly" Item on a Str trait, if you want to put it
somewhere else in the UI.

I'm afraid that I don't know how to get this information out of the
matplotlib plot widget. You will have to consult its documentation,
source, or mailing list.

--
Robert Kern
Enthought
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: matplotlib 3d scatter plot in Traits

Brennan Williams
On 19/06/2012 12:11 p.m., Robert Kern wrote:

> On Tue, Jun 19, 2012 at 10:30 AM, Brennan Williams
> <[hidden email]>  wrote:
>> When I embed a matplotlib 3D scatter plot in my Traits app I can rotate,
>> zoom etc but I don't get the x,y,z positional info down below the plot
>> (and below the matplotlib buttons).
>> You do get that when running a standalone matplotlib script. But in
>> Traits that part of the window/plot is not displayed. Anyone have an
>> idea whether this is a Traits or a matplotlib issue?
> The x,y,z positional information is in a status bar. Status bars are
> part of the decoration of full-blown windows, not embedded widgets.
> When you embed a matplotlib plot inside of a Traits UI, you are just
> embedding the plain plot widget. If you know how to get this
> information out of the matplotlib plot widget, then you can push it
> into a Traits UI StatusBar:
>
>    https://github.com/enthought/traitsui/blob/master/examples/demo/Advanced/Statusbar_demo.py
>
> Or just a "readonly" Item on a Str trait, if you want to put it
> somewhere else in the UI.
>
> I'm afraid that I don't know how to get this information out of the
> matplotlib plot widget. You will have to consult its documentation,
> source, or mailing list.
>
OK, I thought that was probably the case. I'll keep looking in the
matplotlib documentation.

Thanks for the confirmation.

Brennan

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev