TraitsUI and Mayavi integration

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

TraitsUI and Mayavi integration

Eric Larson
Hello,

I am working with a set of Mayavi scenes embedded in a TraitsUI. The problem I'm running into is that if I instantiate a TraitsUI window with Mayavi plots, and load it using "window.edit_traits()" (asynchronously), the window takes a few seconds to appear. This means that if I do things like plot to the embedded Mayavi scenes, things like the lights / light_manager properties aren't available yet (so I can't, e.g., fix the lighting), and doing mlab.screenshot() gives incorrect results. Basically I'm looking for a way to get TraitsUI and/or Mayavi to force a draw, with limited success. Here is a simple code snippet reproducing the issue:

# Enthought imports.
from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

s = ParametricSurface()
m = Mayavi()
m.edit_traits()
mlab.pipeline.surface(s, figure=m.scene.mayavi_scene)

# this one comes up all black
img = mlab.screenshot(figure=m.scene.mayavi_scene)
pl.imshow(img)
# wait a second for the figure to appear, then it works correctly

This is relevant because I am building a GUI with multiple plots that the user can then interact with. But I also want the option to load that GUI, plot things, take a screenshot, and close it without requiring user action.

I found that adding the following code before calling mlab.screenshot helps, but doesn't alleviate all of the problem (aside from seeming pretty hackish):

from pyface.api import GUI
_gui = GUI()
orig_val = _gui.busy
_gui.set_busy(busy=True)
_gui.set_busy(busy=orig_val)
_gui.process_events()

Does anyone know how to force the window.edit_traits() window to show up and redraw, and / or at force Mayavi to draw the scenes?

For sceenshots see:

Thanks,
Eric


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

Re: TraitsUI and Mayavi integration

Pietro Berkes
Hi Eric,

If I understand your problem correctly, all you need to do is initialize the mayavi scene only once the editor for the traitsui item containing it has been initialized.

The easiest way of doing that is making your TraitsUI class a subclass of Handler (e.g., a ModelView). Handler defines a method, init, that is called after the editors have been initialized, e.g.


class MayaviSceneModelView(ModelView):
    """ A Traits UI model-view for a mayavi viewer of 3D scenes. """

    #### 'ModelView' protocol #################################################

    model = Instance(SceneModel)

    #### 'Handler' protocol ###################################################

    def init(self, info):
        """ Initializes the controls of a user interface.

        Parameters
        ----------
        info : UIInfo object
            The UIInfo object associated with the view

        Returns
        -------
        A Boolean, indicating whether the user interface was successfully
        initialized. A True value indicates that the UI can be displayed;
        a False value indicates that the display operation should be
        cancelled. The default implementation returns True without taking
        any other action.

        Description
        -----------
        This method is called after all user interface elements have been
        created, but before the user interface is displayed. Override this
        method to customize the user interface before it is displayed.
        """

        # This needs to be done after the editor has been created.
        self._initialize_mayavi_scene(self.model)

        return True

Best,
Pietro


On Fri, Mar 22, 2013 at 3:55 PM, Eric Larson <[hidden email]> wrote:
Hello,

I am working with a set of Mayavi scenes embedded in a TraitsUI. The problem I'm running into is that if I instantiate a TraitsUI window with Mayavi plots, and load it using "window.edit_traits()" (asynchronously), the window takes a few seconds to appear. This means that if I do things like plot to the embedded Mayavi scenes, things like the lights / light_manager properties aren't available yet (so I can't, e.g., fix the lighting), and doing mlab.screenshot() gives incorrect results. Basically I'm looking for a way to get TraitsUI and/or Mayavi to force a draw, with limited success. Here is a simple code snippet reproducing the issue:

# Enthought imports.
from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

s = ParametricSurface()
m = Mayavi()
m.edit_traits()
mlab.pipeline.surface(s, figure=m.scene.mayavi_scene)

# this one comes up all black
img = mlab.screenshot(figure=m.scene.mayavi_scene)
pl.imshow(img)
# wait a second for the figure to appear, then it works correctly

This is relevant because I am building a GUI with multiple plots that the user can then interact with. But I also want the option to load that GUI, plot things, take a screenshot, and close it without requiring user action.

I found that adding the following code before calling mlab.screenshot helps, but doesn't alleviate all of the problem (aside from seeming pretty hackish):

from pyface.api import GUI
_gui = GUI()
orig_val = _gui.busy
_gui.set_busy(busy=True)
_gui.set_busy(busy=orig_val)
_gui.process_events()

Does anyone know how to force the window.edit_traits() window to show up and redraw, and / or at force Mayavi to draw the scenes?

For sceenshots see:

Thanks,
Eric


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




--
Pietro Berkes
Scientific software developer
Enthought UK


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

Re: TraitsUI and Mayavi integration

Roan LaPlante
Hi Eric,

It isn't necessary to make the class a subclass of handler -- that solution is more general.  MlabSceneModel provides a trait 'scene.activated' after it has been initialized.  Just listen to it:

from traits.api import HasTraits, Instance, on_trait_change
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

    @on_trait_change('scene.activated')
    def start(self):
        s = ParametricSurface()
        mlab.pipeline.surface(s, figure=self.scene.mayavi_scene)

m = Mayavi()
m.configure_traits() # or edit_traits()


R

On Fri, Mar 22, 2013 at 12:08 PM, Pietro Berkes <[hidden email]> wrote:
Hi Eric,

If I understand your problem correctly, all you need to do is initialize the mayavi scene only once the editor for the traitsui item containing it has been initialized.

The easiest way of doing that is making your TraitsUI class a subclass of Handler (e.g., a ModelView). Handler defines a method, init, that is called after the editors have been initialized, e.g.


class MayaviSceneModelView(ModelView):
    """ A Traits UI model-view for a mayavi viewer of 3D scenes. """

    #### 'ModelView' protocol #################################################

    model = Instance(SceneModel)

    #### 'Handler' protocol ###################################################

    def init(self, info):
        """ Initializes the controls of a user interface.

        Parameters
        ----------
        info : UIInfo object
            The UIInfo object associated with the view

        Returns
        -------
        A Boolean, indicating whether the user interface was successfully
        initialized. A True value indicates that the UI can be displayed;
        a False value indicates that the display operation should be
        cancelled. The default implementation returns True without taking
        any other action.

        Description
        -----------
        This method is called after all user interface elements have been
        created, but before the user interface is displayed. Override this
        method to customize the user interface before it is displayed.
        """

        # This needs to be done after the editor has been created.
        self._initialize_mayavi_scene(self.model)

        return True

Best,
Pietro


On Fri, Mar 22, 2013 at 3:55 PM, Eric Larson <[hidden email]> wrote:
Hello,

I am working with a set of Mayavi scenes embedded in a TraitsUI. The problem I'm running into is that if I instantiate a TraitsUI window with Mayavi plots, and load it using "window.edit_traits()" (asynchronously), the window takes a few seconds to appear. This means that if I do things like plot to the embedded Mayavi scenes, things like the lights / light_manager properties aren't available yet (so I can't, e.g., fix the lighting), and doing mlab.screenshot() gives incorrect results. Basically I'm looking for a way to get TraitsUI and/or Mayavi to force a draw, with limited success. Here is a simple code snippet reproducing the issue:

# Enthought imports.
from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

s = ParametricSurface()
m = Mayavi()
m.edit_traits()
mlab.pipeline.surface(s, figure=m.scene.mayavi_scene)

# this one comes up all black
img = mlab.screenshot(figure=m.scene.mayavi_scene)
pl.imshow(img)
# wait a second for the figure to appear, then it works correctly

This is relevant because I am building a GUI with multiple plots that the user can then interact with. But I also want the option to load that GUI, plot things, take a screenshot, and close it without requiring user action.

I found that adding the following code before calling mlab.screenshot helps, but doesn't alleviate all of the problem (aside from seeming pretty hackish):

from pyface.api import GUI
_gui = GUI()
orig_val = _gui.busy
_gui.set_busy(busy=True)
_gui.set_busy(busy=orig_val)
_gui.process_events()

Does anyone know how to force the window.edit_traits() window to show up and redraw, and / or at force Mayavi to draw the scenes?

For sceenshots see:

Thanks,
Eric


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




--
Pietro Berkes
Scientific software developer
Enthought UK


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


The information in this e-mail is intended only for the person to whom it is
addressed. If you believe this e-mail was sent to you in error and the e-mail
contains patient information, please contact the Partners Compliance HelpLine at
http://www.partners.org/complianceline . If the e-mail was sent to you in error
but does not contain patient information, please contact the sender and properly
dispose of the e-mail.




--
Roan LaPlante
Athinoula A. Martinos Center for Biomedical Imaging


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

Re: TraitsUI and Mayavi integration

Brett Ables
In reply to this post by Pietro Berkes
Would calling "scene.render" after changing plot elements update the scene properly?  I've got an embedded mayavi widget in my application and it looks like I call scene.render after making changes.  I'm no expert and this may not be the right way to handle it, just thought I'd chime in.

I've been following these mailing lists for a while and never felt I could contribute anything because it's mostly over my head, but I thought I'd give it a go...

- Brett

On Fri, Mar 22, 2013 at 11:08 AM, Pietro Berkes <[hidden email]> wrote:
Hi Eric,

If I understand your problem correctly, all you need to do is initialize the mayavi scene only once the editor for the traitsui item containing it has been initialized.

The easiest way of doing that is making your TraitsUI class a subclass of Handler (e.g., a ModelView). Handler defines a method, init, that is called after the editors have been initialized, e.g.


class MayaviSceneModelView(ModelView):
    """ A Traits UI model-view for a mayavi viewer of 3D scenes. """

    #### 'ModelView' protocol #################################################

    model = Instance(SceneModel)

    #### 'Handler' protocol ###################################################

    def init(self, info):
        """ Initializes the controls of a user interface.

        Parameters
        ----------
        info : UIInfo object
            The UIInfo object associated with the view

        Returns
        -------
        A Boolean, indicating whether the user interface was successfully
        initialized. A True value indicates that the UI can be displayed;
        a False value indicates that the display operation should be
        cancelled. The default implementation returns True without taking
        any other action.

        Description
        -----------
        This method is called after all user interface elements have been
        created, but before the user interface is displayed. Override this
        method to customize the user interface before it is displayed.
        """

        # This needs to be done after the editor has been created.
        self._initialize_mayavi_scene(self.model)

        return True

Best,
Pietro


On Fri, Mar 22, 2013 at 3:55 PM, Eric Larson <[hidden email]> wrote:
Hello,

I am working with a set of Mayavi scenes embedded in a TraitsUI. The problem I'm running into is that if I instantiate a TraitsUI window with Mayavi plots, and load it using "window.edit_traits()" (asynchronously), the window takes a few seconds to appear. This means that if I do things like plot to the embedded Mayavi scenes, things like the lights / light_manager properties aren't available yet (so I can't, e.g., fix the lighting), and doing mlab.screenshot() gives incorrect results. Basically I'm looking for a way to get TraitsUI and/or Mayavi to force a draw, with limited success. Here is a simple code snippet reproducing the issue:

# Enthought imports.
from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

s = ParametricSurface()
m = Mayavi()
m.edit_traits()
mlab.pipeline.surface(s, figure=m.scene.mayavi_scene)

# this one comes up all black
img = mlab.screenshot(figure=m.scene.mayavi_scene)
pl.imshow(img)
# wait a second for the figure to appear, then it works correctly

This is relevant because I am building a GUI with multiple plots that the user can then interact with. But I also want the option to load that GUI, plot things, take a screenshot, and close it without requiring user action.

I found that adding the following code before calling mlab.screenshot helps, but doesn't alleviate all of the problem (aside from seeming pretty hackish):

from pyface.api import GUI
_gui = GUI()
orig_val = _gui.busy
_gui.set_busy(busy=True)
_gui.set_busy(busy=orig_val)
_gui.process_events()

Does anyone know how to force the window.edit_traits() window to show up and redraw, and / or at force Mayavi to draw the scenes?

For sceenshots see:

Thanks,
Eric


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




--
Pietro Berkes
Scientific software developer
Enthought UK


_______________________________________________
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: TraitsUI and Mayavi integration

Brett Ables
In reply to this post by Roan LaPlante
The embedded mayavi widget as seen here: http://docs.enthought.com/mayavi/mayavi/auto/example_qt_embedding.html uses the "@on_trait_change('scene.activated')" decorator as well.

- Brett

On Fri, Mar 22, 2013 at 11:12 AM, Roan LaPlante <[hidden email]> wrote:
Hi Eric,

It isn't necessary to make the class a subclass of handler -- that solution is more general.  MlabSceneModel provides a trait 'scene.activated' after it has been initialized.  Just listen to it:

from traits.api import HasTraits, Instance, on_trait_change

from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

    @on_trait_change('scene.activated')
    def start(self):
        s = ParametricSurface()
        mlab.pipeline.surface(s, figure=self.scene.mayavi_scene)

m = Mayavi()
m.configure_traits() # or edit_traits()


R

On Fri, Mar 22, 2013 at 12:08 PM, Pietro Berkes <[hidden email]> wrote:
Hi Eric,

If I understand your problem correctly, all you need to do is initialize the mayavi scene only once the editor for the traitsui item containing it has been initialized.

The easiest way of doing that is making your TraitsUI class a subclass of Handler (e.g., a ModelView). Handler defines a method, init, that is called after the editors have been initialized, e.g.


class MayaviSceneModelView(ModelView):
    """ A Traits UI model-view for a mayavi viewer of 3D scenes. """

    #### 'ModelView' protocol #################################################

    model = Instance(SceneModel)

    #### 'Handler' protocol ###################################################

    def init(self, info):
        """ Initializes the controls of a user interface.

        Parameters
        ----------
        info : UIInfo object
            The UIInfo object associated with the view

        Returns
        -------
        A Boolean, indicating whether the user interface was successfully
        initialized. A True value indicates that the UI can be displayed;
        a False value indicates that the display operation should be
        cancelled. The default implementation returns True without taking
        any other action.

        Description
        -----------
        This method is called after all user interface elements have been
        created, but before the user interface is displayed. Override this
        method to customize the user interface before it is displayed.
        """

        # This needs to be done after the editor has been created.
        self._initialize_mayavi_scene(self.model)

        return True

Best,
Pietro


On Fri, Mar 22, 2013 at 3:55 PM, Eric Larson <[hidden email]> wrote:
Hello,

I am working with a set of Mayavi scenes embedded in a TraitsUI. The problem I'm running into is that if I instantiate a TraitsUI window with Mayavi plots, and load it using "window.edit_traits()" (asynchronously), the window takes a few seconds to appear. This means that if I do things like plot to the embedded Mayavi scenes, things like the lights / light_manager properties aren't available yet (so I can't, e.g., fix the lighting), and doing mlab.screenshot() gives incorrect results. Basically I'm looking for a way to get TraitsUI and/or Mayavi to force a draw, with limited success. Here is a simple code snippet reproducing the issue:

# Enthought imports.
from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

s = ParametricSurface()
m = Mayavi()
m.edit_traits()
mlab.pipeline.surface(s, figure=m.scene.mayavi_scene)

# this one comes up all black
img = mlab.screenshot(figure=m.scene.mayavi_scene)
pl.imshow(img)
# wait a second for the figure to appear, then it works correctly

This is relevant because I am building a GUI with multiple plots that the user can then interact with. But I also want the option to load that GUI, plot things, take a screenshot, and close it without requiring user action.

I found that adding the following code before calling mlab.screenshot helps, but doesn't alleviate all of the problem (aside from seeming pretty hackish):

from pyface.api import GUI
_gui = GUI()
orig_val = _gui.busy
_gui.set_busy(busy=True)
_gui.set_busy(busy=orig_val)
_gui.process_events()

Does anyone know how to force the window.edit_traits() window to show up and redraw, and / or at force Mayavi to draw the scenes?

For sceenshots see:

Thanks,
Eric


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




--
Pietro Berkes
Scientific software developer
Enthought UK


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


The information in this e-mail is intended only for the person to whom it is
addressed. If you believe this e-mail was sent to you in error and the e-mail
contains patient information, please contact the Partners Compliance HelpLine at
http://www.partners.org/complianceline . If the e-mail was sent to you in error
but does not contain patient information, please contact the sender and properly
dispose of the e-mail.




--
Roan LaPlante
Athinoula A. Martinos Center for Biomedical Imaging


_______________________________________________
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: TraitsUI and Mayavi integration

Eric Larson
Thanks for the quick responses! I didn't know about the scene.activated parameter, that might be useful. I ran the code you listed Roan, with the following lines at the end (going back to my use case):

...

m = Mayavi()

m.edit_traits() # note using edit_traits() here so further commands are executed

img = mlab.screenshot(figure=m.scene.mayavi_scene)

pl.imshow(img)


Attached screenshots are from running the following script (results in garbled), then from manually re-running the last two lines (since by that time, the edit_traits() window has popped up, it is un-garbled).

Note the use of edit_traits() in addition of the last two lines, which are critical to my actual use case. In this case, "scene.activated" does not solve the problem, as the mlab.screenshot() line still runs before the scene is shown (and thus is garbled). I think this has to do with the asyncronous nature of m.edit_traits(), where the window is not brought up before the mlab.screenshot() call is made. Is there a command to wait for the TraitsUI window to be fully created and displayed that can be used outside the class? This would allow the script to wait until the window is present before moving on to the mlab.screenshot(). That's what I was trying to accomplish with the "from pyface.api import GUI" lines of code, but it didin't work.

I suspect that the proposed subclassing solution would also suffer from this issue, since the scene is probably not being initialized by TraitsUI before the mlab.screenshot() is called. I tried implementing the subclassing solution, but I was unable to do it correctly for this example code, so I couldn't check very well...

I know that it's possible that using m.configure_traits() might work, or that putting the "mlab.screenshot" in a method of the class which checks to see if the screen is activated (and maybe throws an error if it's not or something) might work. However, these are definitely not actually a workable solutions in the non-toy case I'm working with, as we want users to be able to interact with the gui from the command line in arbitrary ways. Basically, we didn't have this issue when using a single mlab figure, since mlab.figure() would cause the window to be brought up fully before returning to the next command, but when the scene is (or multiple scenes are) embedded in a TraitsUI, this isn't the case. It would be nice if we could get that functionality back while using TraitsUI, basically.

Eric




On Fri, Mar 22, 2013 at 9:16 AM, Brett Ables <[hidden email]> wrote:
The embedded mayavi widget as seen here: http://docs.enthought.com/mayavi/mayavi/auto/example_qt_embedding.html uses the "@on_trait_change('scene.activated')" decorator as well.

- Brett

On Fri, Mar 22, 2013 at 11:12 AM, Roan LaPlante <[hidden email]> wrote:
Hi Eric,

It isn't necessary to make the class a subclass of handler -- that solution is more general.  MlabSceneModel provides a trait 'scene.activated' after it has been initialized.  Just listen to it:

from traits.api import HasTraits, Instance, on_trait_change

from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

    @on_trait_change('scene.activated')
    def start(self):
        s = ParametricSurface()
        mlab.pipeline.surface(s, figure=self.scene.mayavi_scene)

m = Mayavi()
m.configure_traits() # or edit_traits()


R

On Fri, Mar 22, 2013 at 12:08 PM, Pietro Berkes <[hidden email]> wrote:
Hi Eric,

If I understand your problem correctly, all you need to do is initialize the mayavi scene only once the editor for the traitsui item containing it has been initialized.

The easiest way of doing that is making your TraitsUI class a subclass of Handler (e.g., a ModelView). Handler defines a method, init, that is called after the editors have been initialized, e.g.


class MayaviSceneModelView(ModelView):
    """ A Traits UI model-view for a mayavi viewer of 3D scenes. """

    #### 'ModelView' protocol #################################################

    model = Instance(SceneModel)

    #### 'Handler' protocol ###################################################

    def init(self, info):
        """ Initializes the controls of a user interface.

        Parameters
        ----------
        info : UIInfo object
            The UIInfo object associated with the view

        Returns
        -------
        A Boolean, indicating whether the user interface was successfully
        initialized. A True value indicates that the UI can be displayed;
        a False value indicates that the display operation should be
        cancelled. The default implementation returns True without taking
        any other action.

        Description
        -----------
        This method is called after all user interface elements have been
        created, but before the user interface is displayed. Override this
        method to customize the user interface before it is displayed.
        """

        # This needs to be done after the editor has been created.
        self._initialize_mayavi_scene(self.model)

        return True

Best,
Pietro


On Fri, Mar 22, 2013 at 3:55 PM, Eric Larson <[hidden email]> wrote:
Hello,

I am working with a set of Mayavi scenes embedded in a TraitsUI. The problem I'm running into is that if I instantiate a TraitsUI window with Mayavi plots, and load it using "window.edit_traits()" (asynchronously), the window takes a few seconds to appear. This means that if I do things like plot to the embedded Mayavi scenes, things like the lights / light_manager properties aren't available yet (so I can't, e.g., fix the lighting), and doing mlab.screenshot() gives incorrect results. Basically I'm looking for a way to get TraitsUI and/or Mayavi to force a draw, with limited success. Here is a simple code snippet reproducing the issue:

# Enthought imports.
from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

s = ParametricSurface()
m = Mayavi()
m.edit_traits()
mlab.pipeline.surface(s, figure=m.scene.mayavi_scene)

# this one comes up all black
img = mlab.screenshot(figure=m.scene.mayavi_scene)
pl.imshow(img)
# wait a second for the figure to appear, then it works correctly

This is relevant because I am building a GUI with multiple plots that the user can then interact with. But I also want the option to load that GUI, plot things, take a screenshot, and close it without requiring user action.

I found that adding the following code before calling mlab.screenshot helps, but doesn't alleviate all of the problem (aside from seeming pretty hackish):

from pyface.api import GUI
_gui = GUI()
orig_val = _gui.busy
_gui.set_busy(busy=True)
_gui.set_busy(busy=orig_val)
_gui.process_events()

Does anyone know how to force the window.edit_traits() window to show up and redraw, and / or at force Mayavi to draw the scenes?

For sceenshots see:

Thanks,
Eric


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




--
Pietro Berkes
Scientific software developer
Enthought UK


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


The information in this e-mail is intended only for the person to whom it is
addressed. If you believe this e-mail was sent to you in error and the e-mail
contains patient information, please contact the Partners Compliance HelpLine at
http://www.partners.org/complianceline . If the e-mail was sent to you in error
but does not contain patient information, please contact the sender and properly
dispose of the e-mail.




--
Roan LaPlante
Athinoula A. Martinos Center for Biomedical Imaging


_______________________________________________
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

Screenshot from 2013-03-22 10:20:02.png (76K) Download Attachment
Screenshot from 2013-03-22 10:20:09.png (71K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: TraitsUI and Mayavi integration

Brett Ables
Have you tried calling "scene.render()" before "mlab.screenshot()"?

When creating frames for an animation that's what I would use to update the scene before creating the screenshot.

- Brett

On Fri, Mar 22, 2013 at 12:52 PM, Eric Larson <[hidden email]> wrote:
Thanks for the quick responses! I didn't know about the scene.activated parameter, that might be useful. I ran the code you listed Roan, with the following lines at the end (going back to my use case):

...

m = Mayavi()

m.edit_traits() # note using edit_traits() here so further commands are executed

img = mlab.screenshot(figure=m.scene.mayavi_scene)

pl.imshow(img)


Attached screenshots are from running the following script (results in garbled), then from manually re-running the last two lines (since by that time, the edit_traits() window has popped up, it is un-garbled).

Note the use of edit_traits() in addition of the last two lines, which are critical to my actual use case. In this case, "scene.activated" does not solve the problem, as the mlab.screenshot() line still runs before the scene is shown (and thus is garbled). I think this has to do with the asyncronous nature of m.edit_traits(), where the window is not brought up before the mlab.screenshot() call is made. Is there a command to wait for the TraitsUI window to be fully created and displayed that can be used outside the class? This would allow the script to wait until the window is present before moving on to the mlab.screenshot(). That's what I was trying to accomplish with the "from pyface.api import GUI" lines of code, but it didin't work.

I suspect that the proposed subclassing solution would also suffer from this issue, since the scene is probably not being initialized by TraitsUI before the mlab.screenshot() is called. I tried implementing the subclassing solution, but I was unable to do it correctly for this example code, so I couldn't check very well...

I know that it's possible that using m.configure_traits() might work, or that putting the "mlab.screenshot" in a method of the class which checks to see if the screen is activated (and maybe throws an error if it's not or something) might work. However, these are definitely not actually a workable solutions in the non-toy case I'm working with, as we want users to be able to interact with the gui from the command line in arbitrary ways. Basically, we didn't have this issue when using a single mlab figure, since mlab.figure() would cause the window to be brought up fully before returning to the next command, but when the scene is (or multiple scenes are) embedded in a TraitsUI, this isn't the case. It would be nice if we could get that functionality back while using TraitsUI, basically.

Eric




On Fri, Mar 22, 2013 at 9:16 AM, Brett Ables <[hidden email]> wrote:
The embedded mayavi widget as seen here: http://docs.enthought.com/mayavi/mayavi/auto/example_qt_embedding.html uses the "@on_trait_change('scene.activated')" decorator as well.

- Brett

On Fri, Mar 22, 2013 at 11:12 AM, Roan LaPlante <[hidden email]> wrote:
Hi Eric,

It isn't necessary to make the class a subclass of handler -- that solution is more general.  MlabSceneModel provides a trait 'scene.activated' after it has been initialized.  Just listen to it:

from traits.api import HasTraits, Instance, on_trait_change

from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

    @on_trait_change('scene.activated')
    def start(self):
        s = ParametricSurface()
        mlab.pipeline.surface(s, figure=self.scene.mayavi_scene)

m = Mayavi()
m.configure_traits() # or edit_traits()


R

On Fri, Mar 22, 2013 at 12:08 PM, Pietro Berkes <[hidden email]> wrote:
Hi Eric,

If I understand your problem correctly, all you need to do is initialize the mayavi scene only once the editor for the traitsui item containing it has been initialized.

The easiest way of doing that is making your TraitsUI class a subclass of Handler (e.g., a ModelView). Handler defines a method, init, that is called after the editors have been initialized, e.g.


class MayaviSceneModelView(ModelView):
    """ A Traits UI model-view for a mayavi viewer of 3D scenes. """

    #### 'ModelView' protocol #################################################

    model = Instance(SceneModel)

    #### 'Handler' protocol ###################################################

    def init(self, info):
        """ Initializes the controls of a user interface.

        Parameters
        ----------
        info : UIInfo object
            The UIInfo object associated with the view

        Returns
        -------
        A Boolean, indicating whether the user interface was successfully
        initialized. A True value indicates that the UI can be displayed;
        a False value indicates that the display operation should be
        cancelled. The default implementation returns True without taking
        any other action.

        Description
        -----------
        This method is called after all user interface elements have been
        created, but before the user interface is displayed. Override this
        method to customize the user interface before it is displayed.
        """

        # This needs to be done after the editor has been created.
        self._initialize_mayavi_scene(self.model)

        return True

Best,
Pietro


On Fri, Mar 22, 2013 at 3:55 PM, Eric Larson <[hidden email]> wrote:
Hello,

I am working with a set of Mayavi scenes embedded in a TraitsUI. The problem I'm running into is that if I instantiate a TraitsUI window with Mayavi plots, and load it using "window.edit_traits()" (asynchronously), the window takes a few seconds to appear. This means that if I do things like plot to the embedded Mayavi scenes, things like the lights / light_manager properties aren't available yet (so I can't, e.g., fix the lighting), and doing mlab.screenshot() gives incorrect results. Basically I'm looking for a way to get TraitsUI and/or Mayavi to force a draw, with limited success. Here is a simple code snippet reproducing the issue:

# Enthought imports.
from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

s = ParametricSurface()
m = Mayavi()
m.edit_traits()
mlab.pipeline.surface(s, figure=m.scene.mayavi_scene)

# this one comes up all black
img = mlab.screenshot(figure=m.scene.mayavi_scene)
pl.imshow(img)
# wait a second for the figure to appear, then it works correctly

This is relevant because I am building a GUI with multiple plots that the user can then interact with. But I also want the option to load that GUI, plot things, take a screenshot, and close it without requiring user action.

I found that adding the following code before calling mlab.screenshot helps, but doesn't alleviate all of the problem (aside from seeming pretty hackish):

from pyface.api import GUI
_gui = GUI()
orig_val = _gui.busy
_gui.set_busy(busy=True)
_gui.set_busy(busy=orig_val)
_gui.process_events()

Does anyone know how to force the window.edit_traits() window to show up and redraw, and / or at force Mayavi to draw the scenes?

For sceenshots see:

Thanks,
Eric


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




--
Pietro Berkes
Scientific software developer
Enthought UK


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


The information in this e-mail is intended only for the person to whom it is
addressed. If you believe this e-mail was sent to you in error and the e-mail
contains patient information, please contact the Partners Compliance HelpLine at
http://www.partners.org/complianceline . If the e-mail was sent to you in error
but does not contain patient information, please contact the sender and properly
dispose of the e-mail.




--
Roan LaPlante
Athinoula A. Martinos Center for Biomedical Imaging


_______________________________________________
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: TraitsUI and Mayavi integration

Eric Larson
Yeah, I have tried mlab.draw(), m.scene.render(), and m.scene.mayavi_scene.render(), and they seem to have no effect.

Eric



On Fri, Mar 22, 2013 at 11:13 AM, Brett Ables <[hidden email]> wrote:
Have you tried calling "scene.render()" before "mlab.screenshot()"?

When creating frames for an animation that's what I would use to update the scene before creating the screenshot.

- Brett


On Fri, Mar 22, 2013 at 12:52 PM, Eric Larson <[hidden email]> wrote:
Thanks for the quick responses! I didn't know about the scene.activated parameter, that might be useful. I ran the code you listed Roan, with the following lines at the end (going back to my use case):

...

m = Mayavi()

m.edit_traits() # note using edit_traits() here so further commands are executed

img = mlab.screenshot(figure=m.scene.mayavi_scene)

pl.imshow(img)


Attached screenshots are from running the following script (results in garbled), then from manually re-running the last two lines (since by that time, the edit_traits() window has popped up, it is un-garbled).

Note the use of edit_traits() in addition of the last two lines, which are critical to my actual use case. In this case, "scene.activated" does not solve the problem, as the mlab.screenshot() line still runs before the scene is shown (and thus is garbled). I think this has to do with the asyncronous nature of m.edit_traits(), where the window is not brought up before the mlab.screenshot() call is made. Is there a command to wait for the TraitsUI window to be fully created and displayed that can be used outside the class? This would allow the script to wait until the window is present before moving on to the mlab.screenshot(). That's what I was trying to accomplish with the "from pyface.api import GUI" lines of code, but it didin't work.

I suspect that the proposed subclassing solution would also suffer from this issue, since the scene is probably not being initialized by TraitsUI before the mlab.screenshot() is called. I tried implementing the subclassing solution, but I was unable to do it correctly for this example code, so I couldn't check very well...

I know that it's possible that using m.configure_traits() might work, or that putting the "mlab.screenshot" in a method of the class which checks to see if the screen is activated (and maybe throws an error if it's not or something) might work. However, these are definitely not actually a workable solutions in the non-toy case I'm working with, as we want users to be able to interact with the gui from the command line in arbitrary ways. Basically, we didn't have this issue when using a single mlab figure, since mlab.figure() would cause the window to be brought up fully before returning to the next command, but when the scene is (or multiple scenes are) embedded in a TraitsUI, this isn't the case. It would be nice if we could get that functionality back while using TraitsUI, basically.

Eric




On Fri, Mar 22, 2013 at 9:16 AM, Brett Ables <[hidden email]> wrote:
The embedded mayavi widget as seen here: http://docs.enthought.com/mayavi/mayavi/auto/example_qt_embedding.html uses the "@on_trait_change('scene.activated')" decorator as well.

- Brett

On Fri, Mar 22, 2013 at 11:12 AM, Roan LaPlante <[hidden email]> wrote:
Hi Eric,

It isn't necessary to make the class a subclass of handler -- that solution is more general.  MlabSceneModel provides a trait 'scene.activated' after it has been initialized.  Just listen to it:

from traits.api import HasTraits, Instance, on_trait_change

from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

    @on_trait_change('scene.activated')
    def start(self):
        s = ParametricSurface()
        mlab.pipeline.surface(s, figure=self.scene.mayavi_scene)

m = Mayavi()
m.configure_traits() # or edit_traits()


R

On Fri, Mar 22, 2013 at 12:08 PM, Pietro Berkes <[hidden email]> wrote:
Hi Eric,

If I understand your problem correctly, all you need to do is initialize the mayavi scene only once the editor for the traitsui item containing it has been initialized.

The easiest way of doing that is making your TraitsUI class a subclass of Handler (e.g., a ModelView). Handler defines a method, init, that is called after the editors have been initialized, e.g.


class MayaviSceneModelView(ModelView):
    """ A Traits UI model-view for a mayavi viewer of 3D scenes. """

    #### 'ModelView' protocol #################################################

    model = Instance(SceneModel)

    #### 'Handler' protocol ###################################################

    def init(self, info):
        """ Initializes the controls of a user interface.

        Parameters
        ----------
        info : UIInfo object
            The UIInfo object associated with the view

        Returns
        -------
        A Boolean, indicating whether the user interface was successfully
        initialized. A True value indicates that the UI can be displayed;
        a False value indicates that the display operation should be
        cancelled. The default implementation returns True without taking
        any other action.

        Description
        -----------
        This method is called after all user interface elements have been
        created, but before the user interface is displayed. Override this
        method to customize the user interface before it is displayed.
        """

        # This needs to be done after the editor has been created.
        self._initialize_mayavi_scene(self.model)

        return True

Best,
Pietro


On Fri, Mar 22, 2013 at 3:55 PM, Eric Larson <[hidden email]> wrote:
Hello,

I am working with a set of Mayavi scenes embedded in a TraitsUI. The problem I'm running into is that if I instantiate a TraitsUI window with Mayavi plots, and load it using "window.edit_traits()" (asynchronously), the window takes a few seconds to appear. This means that if I do things like plot to the embedded Mayavi scenes, things like the lights / light_manager properties aren't available yet (so I can't, e.g., fix the lighting), and doing mlab.screenshot() gives incorrect results. Basically I'm looking for a way to get TraitsUI and/or Mayavi to force a draw, with limited success. Here is a simple code snippet reproducing the issue:

# Enthought imports.
from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

s = ParametricSurface()
m = Mayavi()
m.edit_traits()
mlab.pipeline.surface(s, figure=m.scene.mayavi_scene)

# this one comes up all black
img = mlab.screenshot(figure=m.scene.mayavi_scene)
pl.imshow(img)
# wait a second for the figure to appear, then it works correctly

This is relevant because I am building a GUI with multiple plots that the user can then interact with. But I also want the option to load that GUI, plot things, take a screenshot, and close it without requiring user action.

I found that adding the following code before calling mlab.screenshot helps, but doesn't alleviate all of the problem (aside from seeming pretty hackish):

from pyface.api import GUI
_gui = GUI()
orig_val = _gui.busy
_gui.set_busy(busy=True)
_gui.set_busy(busy=orig_val)
_gui.process_events()

Does anyone know how to force the window.edit_traits() window to show up and redraw, and / or at force Mayavi to draw the scenes?

For sceenshots see:

Thanks,
Eric


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




--
Pietro Berkes
Scientific software developer
Enthought UK


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


The information in this e-mail is intended only for the person to whom it is
addressed. If you believe this e-mail was sent to you in error and the e-mail
contains patient information, please contact the Partners Compliance HelpLine at
http://www.partners.org/complianceline . If the e-mail was sent to you in error
but does not contain patient information, please contact the sender and properly
dispose of the e-mail.




--
Roan LaPlante
Athinoula A. Martinos Center for Biomedical Imaging


_______________________________________________
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



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

Re: TraitsUI and Mayavi integration

Roan LaPlante
Hi Eric,


Take note of this note in the mlab API under mlab.screenshot()

On most systems, this works similarly to taking a screenshot of the rendering window. Thus if it is hidden by another window, you will capture the other window. This limitation is due to the heavy use of the hardware graphics system.


I think it is this that is the cause of your bug; regardless of whether the scene is fully activated or not, by the time you call screenshot the scene has not finished getting onto the screen, so mlab.screenshot() takes bad data.  This is part of the traitsui control flow and not the mayavi control flow.  Traitsui will need to have completely finished rendering all of its components.  There might be a way to do this, I'm not sure and I don't have more time to look through the documentation right now.  I don't think that subclassing a Handler would permit you to take the screenshot at precisely the right point in the processing stream though.

R

On Fri, Mar 22, 2013 at 2:17 PM, Eric Larson <[hidden email]> wrote:
Yeah, I have tried mlab.draw(), m.scene.render(), and m.scene.mayavi_scene.render(), and they seem to have no effect.

Eric



On Fri, Mar 22, 2013 at 11:13 AM, Brett Ables <[hidden email]> wrote:
Have you tried calling "scene.render()" before "mlab.screenshot()"?

When creating frames for an animation that's what I would use to update the scene before creating the screenshot.

- Brett


On Fri, Mar 22, 2013 at 12:52 PM, Eric Larson <[hidden email]> wrote:
Thanks for the quick responses! I didn't know about the scene.activated parameter, that might be useful. I ran the code you listed Roan, with the following lines at the end (going back to my use case):

...

m = Mayavi()

m.edit_traits() # note using edit_traits() here so further commands are executed

img = mlab.screenshot(figure=m.scene.mayavi_scene)

pl.imshow(img)


Attached screenshots are from running the following script (results in garbled), then from manually re-running the last two lines (since by that time, the edit_traits() window has popped up, it is un-garbled).

Note the use of edit_traits() in addition of the last two lines, which are critical to my actual use case. In this case, "scene.activated" does not solve the problem, as the mlab.screenshot() line still runs before the scene is shown (and thus is garbled). I think this has to do with the asyncronous nature of m.edit_traits(), where the window is not brought up before the mlab.screenshot() call is made. Is there a command to wait for the TraitsUI window to be fully created and displayed that can be used outside the class? This would allow the script to wait until the window is present before moving on to the mlab.screenshot(). That's what I was trying to accomplish with the "from pyface.api import GUI" lines of code, but it didin't work.

I suspect that the proposed subclassing solution would also suffer from this issue, since the scene is probably not being initialized by TraitsUI before the mlab.screenshot() is called. I tried implementing the subclassing solution, but I was unable to do it correctly for this example code, so I couldn't check very well...

I know that it's possible that using m.configure_traits() might work, or that putting the "mlab.screenshot" in a method of the class which checks to see if the screen is activated (and maybe throws an error if it's not or something) might work. However, these are definitely not actually a workable solutions in the non-toy case I'm working with, as we want users to be able to interact with the gui from the command line in arbitrary ways. Basically, we didn't have this issue when using a single mlab figure, since mlab.figure() would cause the window to be brought up fully before returning to the next command, but when the scene is (or multiple scenes are) embedded in a TraitsUI, this isn't the case. It would be nice if we could get that functionality back while using TraitsUI, basically.

Eric




On Fri, Mar 22, 2013 at 9:16 AM, Brett Ables <[hidden email]> wrote:
The embedded mayavi widget as seen here: http://docs.enthought.com/mayavi/mayavi/auto/example_qt_embedding.html uses the "@on_trait_change('scene.activated')" decorator as well.

- Brett

On Fri, Mar 22, 2013 at 11:12 AM, Roan LaPlante <[hidden email]> wrote:
Hi Eric,

It isn't necessary to make the class a subclass of handler -- that solution is more general.  MlabSceneModel provides a trait 'scene.activated' after it has been initialized.  Just listen to it:

from traits.api import HasTraits, Instance, on_trait_change

from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

    @on_trait_change('scene.activated')
    def start(self):
        s = ParametricSurface()
        mlab.pipeline.surface(s, figure=self.scene.mayavi_scene)

m = Mayavi()
m.configure_traits() # or edit_traits()


R

On Fri, Mar 22, 2013 at 12:08 PM, Pietro Berkes <[hidden email]> wrote:
Hi Eric,

If I understand your problem correctly, all you need to do is initialize the mayavi scene only once the editor for the traitsui item containing it has been initialized.

The easiest way of doing that is making your TraitsUI class a subclass of Handler (e.g., a ModelView). Handler defines a method, init, that is called after the editors have been initialized, e.g.


class MayaviSceneModelView(ModelView):
    """ A Traits UI model-view for a mayavi viewer of 3D scenes. """

    #### 'ModelView' protocol #################################################

    model = Instance(SceneModel)

    #### 'Handler' protocol ###################################################

    def init(self, info):
        """ Initializes the controls of a user interface.

        Parameters
        ----------
        info : UIInfo object
            The UIInfo object associated with the view

        Returns
        -------
        A Boolean, indicating whether the user interface was successfully
        initialized. A True value indicates that the UI can be displayed;
        a False value indicates that the display operation should be
        cancelled. The default implementation returns True without taking
        any other action.

        Description
        -----------
        This method is called after all user interface elements have been
        created, but before the user interface is displayed. Override this
        method to customize the user interface before it is displayed.
        """

        # This needs to be done after the editor has been created.
        self._initialize_mayavi_scene(self.model)

        return True

Best,
Pietro


On Fri, Mar 22, 2013 at 3:55 PM, Eric Larson <[hidden email]> wrote:
Hello,

I am working with a set of Mayavi scenes embedded in a TraitsUI. The problem I'm running into is that if I instantiate a TraitsUI window with Mayavi plots, and load it using "window.edit_traits()" (asynchronously), the window takes a few seconds to appear. This means that if I do things like plot to the embedded Mayavi scenes, things like the lights / light_manager properties aren't available yet (so I can't, e.g., fix the lighting), and doing mlab.screenshot() gives incorrect results. Basically I'm looking for a way to get TraitsUI and/or Mayavi to force a draw, with limited success. Here is a simple code snippet reproducing the issue:

# Enthought imports.
from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

s = ParametricSurface()
m = Mayavi()
m.edit_traits()
mlab.pipeline.surface(s, figure=m.scene.mayavi_scene)

# this one comes up all black
img = mlab.screenshot(figure=m.scene.mayavi_scene)
pl.imshow(img)
# wait a second for the figure to appear, then it works correctly

This is relevant because I am building a GUI with multiple plots that the user can then interact with. But I also want the option to load that GUI, plot things, take a screenshot, and close it without requiring user action.

I found that adding the following code before calling mlab.screenshot helps, but doesn't alleviate all of the problem (aside from seeming pretty hackish):

from pyface.api import GUI
_gui = GUI()
orig_val = _gui.busy
_gui.set_busy(busy=True)
_gui.set_busy(busy=orig_val)
_gui.process_events()

Does anyone know how to force the window.edit_traits() window to show up and redraw, and / or at force Mayavi to draw the scenes?

For sceenshots see:

Thanks,
Eric


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




--
Pietro Berkes
Scientific software developer
Enthought UK


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


The information in this e-mail is intended only for the person to whom it is
addressed. If you believe this e-mail was sent to you in error and the e-mail
contains patient information, please contact the Partners Compliance HelpLine at
http://www.partners.org/complianceline . If the e-mail was sent to you in error
but does not contain patient information, please contact the sender and properly
dispose of the e-mail.




--
Roan LaPlante
Athinoula A. Martinos Center for Biomedical Imaging


_______________________________________________
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



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


The information in this e-mail is intended only for the person to whom it is
addressed. If you believe this e-mail was sent to you in error and the e-mail
contains patient information, please contact the Partners Compliance HelpLine at
http://www.partners.org/complianceline . If the e-mail was sent to you in error
but does not contain patient information, please contact the sender and properly
dispose of the e-mail.




--
Roan LaPlante
Athinoula A. Martinos Center for Biomedical Imaging


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

Re: TraitsUI and Mayavi integration

Eric Larson
Hey Roan,

This behavior unfortunately extends beyond affecting just the mlab.screenshot() command (which I used here as a starting point since it makes pictures). In the real use case, we also do things like adjust lighting parameters after making the scene(s). If one replaces the `mlab.screenshot()` command in my scripts with:

>>> print m.scene.light_manager.lights


In the script, you'll get the error:


AttributeError: 'NoneType' object has no attribute 'lights'


This is because the scene hasn't been drawn, and scene.light_manager is still None. But if you wait for the window to pop up then do the same command, you get the expected output:


[<tvtk.pyface.light_manager.CameraLight object at 0x6678e30>, <tvtk.pyface.light_manager.CameraLight object at 0x667ee30>, <tvtk.pyface.light_manager.CameraLight object at 0x667ed70>, <tvtk.pyface.light_manager.CameraLight object at 0x66ec4d0>]


Thus it is actually a more general problem than I have made clear. I think you're correct though that I'm really looking for something that will ensure that TraitsUI has finished rendering its components (one of which will be the scene(s)) to avoid these issues.


Eric




On Fri, Mar 22, 2013 at 12:30 PM, Roan LaPlante <[hidden email]> wrote:
Hi Eric,


Take note of this note in the mlab API under mlab.screenshot()

On most systems, this works similarly to taking a screenshot of the rendering window. Thus if it is hidden by another window, you will capture the other window. This limitation is due to the heavy use of the hardware graphics system.


I think it is this that is the cause of your bug; regardless of whether the scene is fully activated or not, by the time you call screenshot the scene has not finished getting onto the screen, so mlab.screenshot() takes bad data.  This is part of the traitsui control flow and not the mayavi control flow.  Traitsui will need to have completely finished rendering all of its components.  There might be a way to do this, I'm not sure and I don't have more time to look through the documentation right now.  I don't think that subclassing a Handler would permit you to take the screenshot at precisely the right point in the processing stream though.

R


On Fri, Mar 22, 2013 at 2:17 PM, Eric Larson <[hidden email]> wrote:
Yeah, I have tried mlab.draw(), m.scene.render(), and m.scene.mayavi_scene.render(), and they seem to have no effect.

Eric



On Fri, Mar 22, 2013 at 11:13 AM, Brett Ables <[hidden email]> wrote:
Have you tried calling "scene.render()" before "mlab.screenshot()"?

When creating frames for an animation that's what I would use to update the scene before creating the screenshot.

- Brett


On Fri, Mar 22, 2013 at 12:52 PM, Eric Larson <[hidden email]> wrote:
Thanks for the quick responses! I didn't know about the scene.activated parameter, that might be useful. I ran the code you listed Roan, with the following lines at the end (going back to my use case):

...

m = Mayavi()

m.edit_traits() # note using edit_traits() here so further commands are executed

img = mlab.screenshot(figure=m.scene.mayavi_scene)

pl.imshow(img)


Attached screenshots are from running the following script (results in garbled), then from manually re-running the last two lines (since by that time, the edit_traits() window has popped up, it is un-garbled).

Note the use of edit_traits() in addition of the last two lines, which are critical to my actual use case. In this case, "scene.activated" does not solve the problem, as the mlab.screenshot() line still runs before the scene is shown (and thus is garbled). I think this has to do with the asyncronous nature of m.edit_traits(), where the window is not brought up before the mlab.screenshot() call is made. Is there a command to wait for the TraitsUI window to be fully created and displayed that can be used outside the class? This would allow the script to wait until the window is present before moving on to the mlab.screenshot(). That's what I was trying to accomplish with the "from pyface.api import GUI" lines of code, but it didin't work.

I suspect that the proposed subclassing solution would also suffer from this issue, since the scene is probably not being initialized by TraitsUI before the mlab.screenshot() is called. I tried implementing the subclassing solution, but I was unable to do it correctly for this example code, so I couldn't check very well...

I know that it's possible that using m.configure_traits() might work, or that putting the "mlab.screenshot" in a method of the class which checks to see if the screen is activated (and maybe throws an error if it's not or something) might work. However, these are definitely not actually a workable solutions in the non-toy case I'm working with, as we want users to be able to interact with the gui from the command line in arbitrary ways. Basically, we didn't have this issue when using a single mlab figure, since mlab.figure() would cause the window to be brought up fully before returning to the next command, but when the scene is (or multiple scenes are) embedded in a TraitsUI, this isn't the case. It would be nice if we could get that functionality back while using TraitsUI, basically.

Eric




On Fri, Mar 22, 2013 at 9:16 AM, Brett Ables <[hidden email]> wrote:
The embedded mayavi widget as seen here: http://docs.enthought.com/mayavi/mayavi/auto/example_qt_embedding.html uses the "@on_trait_change('scene.activated')" decorator as well.

- Brett

On Fri, Mar 22, 2013 at 11:12 AM, Roan LaPlante <[hidden email]> wrote:
Hi Eric,

It isn't necessary to make the class a subclass of handler -- that solution is more general.  MlabSceneModel provides a trait 'scene.activated' after it has been initialized.  Just listen to it:

from traits.api import HasTraits, Instance, on_trait_change

from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

    @on_trait_change('scene.activated')
    def start(self):
        s = ParametricSurface()
        mlab.pipeline.surface(s, figure=self.scene.mayavi_scene)

m = Mayavi()
m.configure_traits() # or edit_traits()


R

On Fri, Mar 22, 2013 at 12:08 PM, Pietro Berkes <[hidden email]> wrote:
Hi Eric,

If I understand your problem correctly, all you need to do is initialize the mayavi scene only once the editor for the traitsui item containing it has been initialized.

The easiest way of doing that is making your TraitsUI class a subclass of Handler (e.g., a ModelView). Handler defines a method, init, that is called after the editors have been initialized, e.g.


class MayaviSceneModelView(ModelView):
    """ A Traits UI model-view for a mayavi viewer of 3D scenes. """

    #### 'ModelView' protocol #################################################

    model = Instance(SceneModel)

    #### 'Handler' protocol ###################################################

    def init(self, info):
        """ Initializes the controls of a user interface.

        Parameters
        ----------
        info : UIInfo object
            The UIInfo object associated with the view

        Returns
        -------
        A Boolean, indicating whether the user interface was successfully
        initialized. A True value indicates that the UI can be displayed;
        a False value indicates that the display operation should be
        cancelled. The default implementation returns True without taking
        any other action.

        Description
        -----------
        This method is called after all user interface elements have been
        created, but before the user interface is displayed. Override this
        method to customize the user interface before it is displayed.
        """

        # This needs to be done after the editor has been created.
        self._initialize_mayavi_scene(self.model)

        return True

Best,
Pietro


On Fri, Mar 22, 2013 at 3:55 PM, Eric Larson <[hidden email]> wrote:
Hello,

I am working with a set of Mayavi scenes embedded in a TraitsUI. The problem I'm running into is that if I instantiate a TraitsUI window with Mayavi plots, and load it using "window.edit_traits()" (asynchronously), the window takes a few seconds to appear. This means that if I do things like plot to the embedded Mayavi scenes, things like the lights / light_manager properties aren't available yet (so I can't, e.g., fix the lighting), and doing mlab.screenshot() gives incorrect results. Basically I'm looking for a way to get TraitsUI and/or Mayavi to force a draw, with limited success. Here is a simple code snippet reproducing the issue:

# Enthought imports.
from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.sources.api import ParametricSurface
from mayavi import mlab
import pylab as pl
pl.ion()


class Mayavi(HasTraits):
    scene = Instance(MlabSceneModel, ())
    view = View(Item(name='scene', editor=SceneEditor(),
                     show_label=False, resizable=True, height=250,
                     width=500))

s = ParametricSurface()
m = Mayavi()
m.edit_traits()
mlab.pipeline.surface(s, figure=m.scene.mayavi_scene)

# this one comes up all black
img = mlab.screenshot(figure=m.scene.mayavi_scene)
pl.imshow(img)
# wait a second for the figure to appear, then it works correctly

This is relevant because I am building a GUI with multiple plots that the user can then interact with. But I also want the option to load that GUI, plot things, take a screenshot, and close it without requiring user action.

I found that adding the following code before calling mlab.screenshot helps, but doesn't alleviate all of the problem (aside from seeming pretty hackish):

from pyface.api import GUI
_gui = GUI()
orig_val = _gui.busy
_gui.set_busy(busy=True)
_gui.set_busy(busy=orig_val)
_gui.process_events()

Does anyone know how to force the window.edit_traits() window to show up and redraw, and / or at force Mayavi to draw the scenes?

For sceenshots see:

Thanks,
Eric


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




--
Pietro Berkes
Scientific software developer
Enthought UK


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


The information in this e-mail is intended only for the person to whom it is
addressed. If you believe this e-mail was sent to you in error and the e-mail
contains patient information, please contact the Partners Compliance HelpLine at
http://www.partners.org/complianceline . If the e-mail was sent to you in error
but does not contain patient information, please contact the sender and properly
dispose of the e-mail.




--
Roan LaPlante
Athinoula A. Martinos Center for Biomedical Imaging


_______________________________________________
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



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


The information in this e-mail is intended only for the person to whom it is
addressed. If you believe this e-mail was sent to you in error and the e-mail
contains patient information, please contact the Partners Compliance HelpLine at
http://www.partners.org/complianceline . If the e-mail was sent to you in error
but does not contain patient information, please contact the sender and properly
dispose of the e-mail.




--
Roan LaPlante
Athinoula A. Martinos Center for Biomedical Imaging


_______________________________________________
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: TraitsUI and Mayavi integration

Gael Varoquaux
On Fri, Mar 22, 2013 at 12:49:43PM -0700, Eric Larson wrote:
> This behavior unfortunately extends beyond affecting just the mlab.screenshot()
> command (which I used here as a starting point since it makes pictures). In the
> real use case, we also do things like adjust lighting parameters after making
> the scene(s). If one replaces the `mlab.screenshot()` command in my scripts
> with:


> >>> print m.scene.light_manager.lights

Do you get this error when you do it in the handler of 'scene.activated'?
If you are using a different code path, than I don't see how you can
garantee the ordering in which events are executed. In the code example
that you sent, the mlab.screenshot function was called in the main
program path, and not in a 'scene.activated' handler, and thus you cannot
control in what order it is processed by the event loop.

I was about to added that adding a '_gui.process_events()' might help,
but would be fragile. However, I see that you already tried and came to
this conclusion. You could do something like:

while not scene.activated:
   _gui.process_events()

but really this is hackish, and you should follow the advice given in the
documentation and use a handler on scene.activated, the warning box at
the bottom of the following section:
http://docs.enthought.com/mayavi/mayavi/building_applications.html#making-the-visualization-live

HTH,

Gaël


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

Re: TraitsUI and Mayavi integration

Eric Larson
Hey Gael,

Thanks for that link -- I had missed that warning when building the application. Might be worth adding the same warning (or a link to it) on the other examples of multi-scene applications, such as:


I think that putting the calls in the scene.activated handler would work. However, this will not work for our use case, as we want users to be able to script arbitrary sets of scene-related actions that may well rely on the scene having been activated. It's unfortunate that there is no way to "force" TraitsUI activate / draw the window (thus activating the mayavi plot) before continuing down the main program path, since "mlab.figure()" seems to guarantee it.

Our motivation behind using TraitsUI is that we used to change from using a single view of our data (which could be achieved via mlab.figure()), to using multiple views. Is there any way to do this other than using TraitsUI? If not, it might be worth making it clearer in the documentation that this is a limitation of moving from mlab.figure()-based plots, where scene.activated seems to be guaranteed, to using multiple views (and TraitsUI), where scene.activated cannot be stably guaranteed.

Eric



On Mon, Mar 25, 2013 at 9:58 AM, Gael Varoquaux <[hidden email]> wrote:
On Fri, Mar 22, 2013 at 12:49:43PM -0700, Eric Larson wrote:
> This behavior unfortunately extends beyond affecting just the mlab.screenshot()
> command (which I used here as a starting point since it makes pictures). In the
> real use case, we also do things like adjust lighting parameters after making
> the scene(s). If one replaces the `mlab.screenshot()` command in my scripts
> with:


> >>> print m.scene.light_manager.lights

Do you get this error when you do it in the handler of 'scene.activated'?
If you are using a different code path, than I don't see how you can
garantee the ordering in which events are executed. In the code example
that you sent, the mlab.screenshot function was called in the main
program path, and not in a 'scene.activated' handler, and thus you cannot
control in what order it is processed by the event loop.

I was about to added that adding a '_gui.process_events()' might help,
but would be fragile. However, I see that you already tried and came to
this conclusion. You could do something like:

while not scene.activated:
   _gui.process_events()

but really this is hackish, and you should follow the advice given in the
documentation and use a handler on scene.activated, the warning box at
the bottom of the following section:
http://docs.enthought.com/mayavi/mayavi/building_applications.html#making-the-visualization-live

HTH,

Gaël


_______________________________________________
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: TraitsUI and Mayavi integration

Gael Varoquaux
On Mon, Mar 25, 2013 at 10:24:41AM -0700, Eric Larson wrote:
> I think that putting the calls in the scene.activated handler would work.
> However, this will not work for our use case, as we want users to be able to
> script arbitrary sets of scene-related actions that may well rely on the scene
> having been activated. It's unfortunate that there is no way to "force"
> TraitsUI activate / draw the window (thus activating the mayavi plot) before
> continuing down the main program path, since "mlab.figure()" seems to guarantee
> it.

There is no 'main program path' the minute that you are calling
'edit_traits'. Thinking in these terms is bound to break. I think that
you need to take a step back and think about how you structure your
program in term of GUI events and event loop. You cannot simply ignore
that you have a GUI running and that it is processing events in an order
that you do not control. You can do many hacks to try to hide this, but at
the end of the day, they will break, and leave you with a code base more
complex and more fragile than if you had coded everything cleanly with
event processing.

You could try reading on GUIs and even-driven programming. I
unfortunately don't know any good references. Maybe section 2 and 3 of
the following document might help:
http://gael-varoquaux.info/computers/traits_tutorial/traits_tutorial.html

As you do not seem to mention explicitely starting the event loop, I
believe that you may be running your code inside 'ipython -wthread', in
which case you must realise that there are 2 threads running, one with
the GUI event loop, and the other with the IPythn execution loop.

HTH,

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

Re: TraitsUI and Mayavi integration

Eric Larson

There is no 'main program path' the minute that you are calling
'edit_traits'. Thinking in these terms is bound to break. I think that
you need to take a step back and think about how you structure your
program in term of GUI events and event loop. You cannot simply ignore
that you have a GUI running and that it is processing events in an order
that you do not control. You can do many hacks to try to hide this, but at
the end of the day, they will break, and leave you with a code base more
complex and more fragile than if you had coded everything cleanly with
event processing.

It makes sense that there is no clearly defined "main program path", since there are multiple threads running at the point of GUI creation. I guess what I'm not clear about is how calling `edit_traits` must differ, from this perspective, from calling `mlab.figure()`. I assumed that in both cases they caused a GUI, with its own events loop, to be started (processing events in an order outside of user control), and thus in both cases there would be no "main program path" in that sense. Is the difference that, in the `mlab.figure()` case, it is doing a good job of hiding this fact from you, and allowing you to assume it's not an issue (i.e., letting you call plotting commands subsequently from the command line)? Or is `mlab.figure()` doing something else that I'm missing? It seems like all of the non-TraitsUI examples rely on having this sense of a "main program path" following the `mlab.figure()` creation, which has led to my confusion as to why the TraitsUI case can't or shouldn't be thought of analogously (unless it can't be "synchronized" like the mlab.figure() can).

Sorry if I'm being dense on this one, I'm just trying hard to find a way to have stable `mlab.figure()` - like functionality with multiple Mayavi scenes to display to. It seems like this must be possible...

Eric


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