Monday 20 October 2014

Embed 2D or 3D Matplotlib plots in wxPython

    I am working on an application and needed to embed a matplotlib plot within a wxPython frame. One of the reason to embed was that, I was unable to close or redraw a 3D matplotlib plot from wxPython. Here's the code that accomplished my need.

1:  import wx  
2:  import matplotlib.pyplot as plt  
3:  from mpl_toolkits.mplot3d import Axes3D  
4:  from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas  
5:  from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg  
6:  import numpy as np  
7:    
8:    
9:  # INTPUTS  
10:  dimension = 'two'  
11:  task = 'tracking'  
12:  if dimension == 'three'and task == 'tracking':  # three dimensional plot  
13:    n_plot_inputs = 6  
14:  elif dimension == 'two' and task == 'tracking': # two dimensional plot  
15:    n_plot_inputs = 4  
16:  elif dimension == 'three' and task == 'goal':  # three dimensional plot  
17:    n_plot_inputs = 3  
18:  elif dimension == 'two' and task == 'goal':   # two dimensional plot  
19:    n_plot_inputs = 2  
20:    
21:    
22:  x_UAV = [2,3,4,5,6]  
23:  y_UAV = [3,4,2,6,4]  
24:  z_UAV = [7,3,2,2,6]  
25:    
26:  x_target = [6,4,3,4,3]  
27:  y_target = [6,2,6,2,6]  
28:  z_target = [6,2,2,6,2]  
29:    
30:    
31:  class Plotting(object):  
32:    def __init__(self, axes, *args):  
33:      x = args[1]  
34:      y = args[2]  
35:      if dimension == 'two':  
36:        axes.plot(x,y,args[0])  
37:      else:  
38:        z = args[3]  
39:        axes.plot(np.array(x), np.array(y),np.array(z),args[0])  
40:    
41:    
42:  class PlotFrame(wx.Frame):  
43:    def __init__(self):  
44:      wx.Frame.__init__(self, None, -1, 'Simulation', (756,100), (600,532))  
45:      self.figure = plt.figure()  
46:      plt.ion()  
47:      if dimension == 'two':  
48:        self.axes = plt.axes()  
49:      else:  
50:        self.axes = plt.axes(projection = '3d')  
51:        self.axes.set_zlabel('z axis')  
52:      plot_UAV = Plotting(self.axes, '-xb', x_UAV, y_UAV, z_UAV)  
53:      if task == 'tracking':  
54:        plot_target = Plotting(self.axes, '-og', x_target, y_target, z_target)  
55:      self.axes.set_xlabel('x axis')  
56:      self.axes.set_ylabel('y axis')  
57:      self.canvas = FigureCanvas(self, -1, self.figure)  
58:      self.sizer = wx.BoxSizer(wx.VERTICAL)  
59:      self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)  
60:      self.SetSizer(self.sizer)  
61:      self.add_toolbar()  
62:    
63:    def add_toolbar(self):  
64:      self.toolbar = NavigationToolbar2WxAgg(self.canvas)  
65:      self.toolbar.Realize()  
66:      if wx.Platform == '__WXMAC__':  
67:        self.SetToolBar(self.toolbar)  
68:      else:  
69:        tw, th = self.toolbar.GetSizeTuple()  
70:        fw, fh = self.canvas.GetSizeTuple()  
71:        self.toolbar.SetSize(wx.Size(fw, th))  
72:        self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)  
73:      self.toolbar.update()  
74:    
75:    
76:  class App(wx.App):  
77:    def OnInit(self):  
78:      self.plotframe = PlotFrame()  
79:      self.plotframe.Center()  
80:      self.plotframe.Show()  
81:      return True  
82:    
83:  if __name__ == '__main__':  
84:    app = App(False)  
85:    app.MainLoop()  

The one problem with the embedded 3D plot is that I cannot pan or zoom or rotate the plot like the normal matplotlib plot. A little help regarding this is always appreciated.


No comments:

Post a Comment