matplotlib and PyQt plotting a surface

1.9k views Asked by At

I created a 3D plot using matplotlib as this:

fig = pylab.figure()
ax = Axes3D( fig )
surf = ax.plot_surface( X, Y, Z, cmap=cm.gray_r, linewidth=0, antialiased=True )
fig.canvas.set_window_title( "Distance" )
pylab.show()

It's fantastic: I see the surface in grays-cale and I can interact with it ( turn the surface, move plot, ... )

Now I need to put this plot in a PyQt form. I created a class inherit from QMainWindow doing this:

class ViewerForm(QMainWindow):
   def __init__(self, p_parent=None, p_data=None):
      QMainWindow.__init__( self, parent=p_parent )

      self.main_frame = QWidget( )
      self.figure = pyplot.figure()
      self.axis = Axes3D( self.figure )
      self.canvas = FigureCanvas( self.figure )
      self.canvas.setParent( self.main_frame )
      self.mpl_toolbar = NavigationToolbar( self.canvas, self.main_frame )

      self.X, self.Y = np.meshgrid( p_data[ "axis_x" ], p_data[ "axis_y" ] )
      self.Z = p_data[ "values_z" ]

      self.surface = self.axis.plot_surface( self.X, self.Y, self.Z, cmap=cm.gray, linewidth=0, antialiased=True )

      vbox = QVBoxLayout( )
      vbox.addWidget( self.canvas )
      vbox.addWidget( self.mpl_toolbar )
      self.main_frame.setLayout( vbox )

      self.setCentralWidget( self.main_frame )

When I show this form I can see the surface in gray-scale as the first plot but I can't interact with this: I can't move the surface clicking with mouse. Anyone can say me what I'm doing wrong or what I misunderstood?

2

There are 2 answers

0
Dan On BEST ANSWER

I had this before and it confused me a lot. Zhenya is right about the mouse clicking.

By default, control of the plot by mouse is turned off when the axis is cleared/replotted. I have no idea quite why this would be so, but you need to initiate mouse interactions again:

self.surface = self.axis.plot_surface( self.X, self.Y, self.Z, cmap=cm.gray, linewidth=0, antialiased=True )
self.axis.mouse_init()
0
ev-br On

I think you need to register a callback function for the mouse clicks, like in this cookbook example: http://www.scipy.org/Cookbook/Matplotlib/Interactive_Plotting