2011-03-01 6 views
4

파이썬과 wxpython으로 matplotlib를 사용하여 그래프를 업데이트하려고 벽에 머리를 부딪 치고 있습니다. 버튼을 누르고 wx.notebook에 중첩 된 그래프에 데이터를 추가하고 싶습니다. 아래는 코드입니다. 가이드로 this example를 사용하여 도움파이썬과 Matplotlib로 플롯을 업데이트하는 방법

import wx 
import matplotlib as mpl 
import matplotlib.pyplot as plt 
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas 

class Plot(wx.Panel): 
    def __init__(self, parent, id = -1, dpi = None, **kwargs): 
     wx.Panel.__init__(self, parent, id=id, **kwargs) 
     self.figure = mpl.figure.Figure(dpi=dpi, figsize=(2,2)) 
     self.canvas = Canvas(self, -1, self.figure) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.canvas,1,wx.EXPAND) 
     self.SetSizer(sizer) 

class JBC(wx.Frame): 
    def __init__(self, parent, id, title): 
     wx.Frame.__init__(self, parent, id, title, size=(600,600)) 
     self.SetBackgroundColour(wx.Colour(236, 233, 216)) 

     self.nbG = wx.Notebook(self, -1, style=0, size=(400,400), pos=(0,0))  
     self.gSheet1 = self.add("Test").gca() 

     calcButton = wx.Button(self, wx.NewId(), "Update", pos=(0, self.nbG.Position.y+400)) 

     #self.gSheet1.hold(False) 
     #self.gSheet1.set_xlim(0,20) 
     #self.gSheet1.set_ylim(0,20) 
     #for i in range (2): 
     # self.gSheet1.plot([0,10],[1*i,1+i]) 

     #axes2 = plotter.add('figure 2').gca() 
     #axes2.plot([1,2,3,4,5],[2,1,4,2,3]) 

     self.Bind(wx.EVT_BUTTON, self.OnCalculate, calcButton) 

     self.Show(True) 

    def OnCalculate(self, event): 
     self.gSheet1.set_xlim(0,20) 
     self.gSheet1.set_ylim(0,20) 
     self.gSheet1.plot([1,2,3,4,5],[2,1,4,2,3]) 
     self.Update() 

    def add(self,name="plot"): 
     page = Plot(self.nbG) 
     self.nbG.AddPage(page,name) 
     return page.figure 

    def Update(self): 
     self.gSheet1.clear() 
     plt.draw() 
     print "Tried to redraw" 


app = wx.App() 
JBC(None, -1, "Test Title") 
app.MainLoop() 

답변

2

에 대한

감사합니다, 아마도이 시도 :

""" 
Based on Tkinter bouncing ball code: 
http://stackoverflow.com/q/13660042/190597 (arynaq) and 
http://eli.thegreenplace.net/2008/08/01/matplotlib-with-wxpython-guis/ 
""" 

import wx 
import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.figure as mplfig 
import scipy.spatial.distance as dist 
import matplotlib.backends.backend_wxagg as mwx 

class Frame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, wx.ID_ANY, size = (800, 600)) 
     self.panel = wx.Panel(self)   
     self.fig = mplfig.Figure(figsize = (5, 4), dpi = 100) 
     self.ax = self.fig.add_subplot(111) 
     self.vbox = wx.BoxSizer(wx.VERTICAL)   
     self.canvas = mwx.FigureCanvasWxAgg(self.panel, wx.ID_ANY, self.fig) 
     self.toolbar = mwx.NavigationToolbar2WxAgg(self.canvas) 
     self.button = wx.Button(self.panel, wx.ID_ANY, "Quit") 
     self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) 
     self.vbox.Add(self.toolbar, 0, wx.EXPAND)   
     self.vbox.Add(
      self.button, 0, border = 3, 
      flag = wx.ALIGN_LEFT | wx.ALL | wx.ALIGN_CENTER_VERTICAL) 
     self.panel.SetSizer(self.vbox) 
     self.vbox.Fit(self) 
     self.toolbar.update() 
     self.update = self.animate().next 
     self.timer = wx.Timer(self) 
     self.timer.Start(1) 
     self.Bind(wx.EVT_BUTTON, self.OnCloseWindow, self.button)   
     self.Bind(wx.EVT_TIMER, lambda event: self.update()) 
     self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) 

    def OnCloseWindow(self, evt): 
     self.timer.Stop() 
     del self.timer 
     self.Destroy() 

    def animate(self): 
     N = 100            #Number of particles 
     R = 10000           #Box width 
     pR = 5            #Particle radius 

     r = np.random.randint(0, R, (N, 2))     #Position vector 
     v = np.random.randint(-R/100, R/100, (N, 2))   #velocity vector 
     a = np.array([0, -10])        #Forces 
     v_limit = R/2          #Speedlimit 

     line, = self.ax.plot([], 'o') 
     line2, = self.ax.plot([], 'o')       #Track a particle 
     self.ax.set_xlim(0, R+pR) 
     self.ax.set_ylim(0, R+pR)   

     while True: 
      v = v+a           #Advance 
      r = r+v 

      #Collision tests 
      r_hit_x0 = np.where(r[:, 0]<0)     #Hit floor? 
      r_hit_x1 = np.where(r[:, 0]>R)     #Hit roof? 
      r_hit_LR = np.where(r[:, 1]<0)     #Left wall? 
      r_hit_RR = np.where(r[:, 1]>R)     #Right wall? 

      #Stop at walls 
      r[r_hit_x0, 0] = 0 
      r[r_hit_x1, 0] = R 
      r[r_hit_LR, 1] = 0 
      r[r_hit_RR, 1] = R 

      #Reverse velocities 
      v[r_hit_x0, 0] = -0.9*v[r_hit_x0, 0] 
      v[r_hit_x1, 0] = -v[r_hit_x1, 0] 
      v[r_hit_LR, 1] = -0.95*v[r_hit_LR, 1] 
      v[r_hit_RR, 1] = -0.99*v[r_hit_RR, 1] 

      #Collisions 
      D = dist.squareform(dist.pdist(r)) 
      ind1, ind2 = np.where(D < pR) 
      unique = (ind1 < ind2) 
      ind1 = ind1[unique] 
      ind2 = ind2[unique] 

      for i1, i2 in zip(ind1, ind2): 
       eps = np.random.rand() 
       vtot = v[i1, :]+v[i2, :] 
       v[i1, :] = -(1-eps)*vtot 
       v[i2, :] = -eps*vtot 

      line.set_ydata(r[:, 1]) 
      line.set_xdata(r[:, 0]) 
      line2.set_ydata(r[:N/5, 1]) 
      line2.set_xdata(r[:N/5, 0]) 
      self.canvas.draw() 
      yield True 

def main(): 
    app = wx.App(False) 
    frame = Frame() 
    frame.Show(True) 
    app.MainLoop() 

if __name__ == '__main__': 
    main() 
:

import wx 
import matplotlib as mpl 
mpl.use('WXAgg') 
import matplotlib.pyplot as plt 
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas 

class Plot(wx.Panel): 
    def __init__(self, parent, id = -1, dpi = None, **kwargs): 
     wx.Panel.__init__(self, parent, id=id, **kwargs) 
     self.figure = mpl.figure.Figure(dpi=dpi, figsize=(2,2)) 
     self.canvas = Canvas(self, -1, self.figure) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.canvas,1,wx.EXPAND) 
     self.SetSizer(sizer) 

class JBC(wx.Frame): 
    def __init__(self, parent, id, title): 
     wx.Frame.__init__(self, parent, id, title, size=(600,600)) 
     self.SetBackgroundColour(wx.Colour(236, 233, 216)) 

     self.nbG = wx.Notebook(self, -1, style=0, size=(400,400), pos=(0,0))  
     self.gSheet1 = self.add("Test").gca() 

     calcButton = wx.Button(self, wx.NewId(), "Update", pos=(0, self.nbG.Position.y+400)) 

     #self.gSheet1.hold(False) 
     #self.gSheet1.set_xlim(0,20) 
     #self.gSheet1.set_ylim(0,20) 
     #for i in range (2): 
     # self.gSheet1.plot([0,10],[1*i,1+i]) 

     #axes2 = plotter.add('figure 2').gca() 
     #axes2.plot([1,2,3,4,5],[2,1,4,2,3]) 

     self.Bind(wx.EVT_BUTTON, self.OnCalculate, calcButton)   
     # self.Show(True) 

    def OnCalculate(self, event): 
     self.gSheet1.set_xlim(0,20) 
     self.gSheet1.set_ylim(0,20) 
     self.gSheet1.plot([1,2,3,4,5],[2,1,4,2,3]) 
     self.Update() 

    def add(self,name="plot"): 
     page = Plot(self.nbG) 
     self.nbG.AddPage(page,name) 
     return page.figure 

    def Update(self): 
     self.gSheet1.clear() 
     plt.draw() 
     print "Tried to redraw" 

if __name__ == '__main__': 
    app = wx.App() 
    frame=JBC(None, -1, "Test Title") 
    frame.Show() 
    app.MainLoop() 

은 애니메이션 그림을 그릴하기 matplotlib를 사용하는 것도 가능하다

+0

업데이트 버튼을 사용하는 대신 여기서 matplotlib과 함께 동적 플로팅을 사용할 수 있습니까? –

+0

@BhoomikaSheth : 예, http://eli.thegreenplace.net/2008/08/01/matplotlib-with-wxpython-guis/를 참조하십시오. – unutbu