I need to load multiple scenes with option to switch them. Something like on the image:
For button "1" something like mlab.points3d(x1, y1, z1, s1, color=blue)
For button "2" something like mlab.points3d(x2, y2, z2, s2, color=red)
For button "3" something like mlab.points3d(x3, y3, z3, s3, color=green)
How to manage drawing inside another scene? (I suppose that mlab.points3d
should be done before option to switch between scenes).
And how to define buttons for scheme switching?
Here is an example of how to embed a mayavi plot within pyqt with several buttons. It is based on the Qt embedding example from the mayavi website. If you want to write a relatively large application I would advise you to move the code that is now at the bottom under the if main == "main" line into several seperate classes.
from pyface.qt import QtGui, QtCore
from traits.api import HasTraits, Instance, on_trait_change
from traitsui.api import View, Item
from mayavi.core.ui.api import MayaviScene, MlabSceneModel, \
SceneEditor
################################################################################
#The actual visualization
class Visualization(HasTraits):
scene = Instance(MlabSceneModel, ())
@on_trait_change('scene.activated')
def update_plot(self):
# This function is called when the view is opened. We don't
# populate the scene when the view is not yet open, as some
# VTK features require a GLContext.
# We can do normal mlab calls on the embedded scene.
self.scene.mlab.clf()
self.scene.mlab.test_points3d()
def second_plot(self):
self.scene.mlab.clf()
from numpy import sin, cos, mgrid, pi, sqrt
u, v = mgrid[- 0.035:pi:0.01, - 0.035:pi:0.01]
X = 2 / 3. * (cos(u) * cos(2 * v)
+ sqrt(2) * sin(u) * cos(v)) * cos(u) / (sqrt(2) -
sin(2 * u) * sin(3 * v))
Y = 2 / 3. * (cos(u) * sin(2 * v) -
sqrt(2) * sin(u) * sin(v)) * cos(u) / (sqrt(2)
- sin(2 * u) * sin(3 * v))
Z = -sqrt(2) * cos(u) * cos(u) / (sqrt(2) - sin(2 * u) * sin(3 * v))
S = sin(u)
self.scene.mlab.mesh(X, Y, Z, scalars=S, colormap='YlGnBu', )
def third_plot(self):
self.scene.mlab.clf()
self.scene.mlab.test_plot3d()
# the layout of the dialog screated
view = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene),
height=250, width=300, show_label=False),
resizable=True # We need this to resize with the parent widget
)
################################################################################
# The QWidget containing the visualization, this is pure PyQt4 code.
class MayaviQWidget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
layout = QtGui.QVBoxLayout(self)
layout.setContentsMargins(0,0,0,0)
layout.setSpacing(0)
self.visualization = Visualization()
# The edit_traits call will generate the widget to embed.
self.ui = self.visualization.edit_traits(parent=self,
kind='subpanel').control
layout.addWidget(self.ui)
self.ui.setParent(self)
if __name__ == "__main__":
# Don't create a new QApplication, it would unhook the Events
# set by Traits on the existing QApplication. Simply use the
# '.instance()' method to retrieve the existing one.
app = QtGui.QApplication.instance()
container = QtGui.QWidget()
mayavi_widget = MayaviQWidget(container)
container.setWindowTitle("Embedding Mayavi in a PyQt4 Application")
# define a "complex" layout to test the behaviour
layout = QtGui.QHBoxLayout(container)
button_container = QtGui.QWidget()
button_layout = QtGui.QVBoxLayout(button_container)
button1 = QtGui.QPushButton('1')
button1.clicked.connect(mayavi_widget.visualization.update_plot)
button_layout.addWidget(button1)
button2 = QtGui.QPushButton('2')
button2.clicked.connect(mayavi_widget.visualization.second_plot)
button_layout.addWidget(button2)
button3 = QtGui.QPushButton('3')
button3.clicked.connect(mayavi_widget.visualization.third_plot)
button_layout.addWidget(button3)
layout.addWidget(button_container)
button_container.show()
layout.addWidget(mayavi_widget)
container.show()
window = QtGui.QMainWindow()
window.setCentralWidget(container)
window.show()
# Start the main event loop.
app.exec_()