2010-03-14 7 views
11

FigureCanvasWxAgg 인스턴스를 새로 고치는 방법을 이해할 수 없습니다.matplotlib : figure.canvas를 새로 고치는 방법


import wx 
import matplotlib 
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas 
from matplotlib.figure import Figure 

class MainFrame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, wx.NewId(), "Main") 
     self.sizer = wx.BoxSizer(wx.VERTICAL) 

     self.figure = Figure(figsize=(1,2)) 
     self.axe = self.figure.add_subplot(111) 
     self.figurecanvas = FigureCanvas(self, -1, self.figure) 

     self.buttonPlot = wx.Button(self, wx.NewId(), "Plot") 
     self.buttonClear = wx.Button(self, wx.NewId(), "Clear") 

     self.sizer.Add(self.figurecanvas, proportion=1, border=5, flag=wx.ALL | wx.EXPAND) 
     self.sizer.Add(self.buttonPlot, proportion=0, border=2, flag=wx.ALL) 
     self.sizer.Add(self.buttonClear, proportion=0, border=2, flag=wx.ALL) 
     self.SetSizer(self.sizer) 

     self.figurecanvas.Bind(wx.EVT_LEFT_DCLICK, self.on_dclick) 
     self.buttonPlot.Bind(wx.EVT_BUTTON, self.on_button_plot) 
     self.buttonClear.Bind(wx.EVT_BUTTON, self.on_button_clear) 

     self.subframe_opened = False 

    def on_dclick(self, evt): 
     self.subframe = SubFrame(self, self.figure) 
     self.subframe.Show(True) 
     self.subframe_opened = True 

    def on_button_plot(self, evt): 
     self.axe.plot(range(10), color='green') 
     self.figurecanvas.draw() 

    def on_button_clear(self, evt): 
     if self.subframe_opened: 
      self.subframe.Close() 
     self.figure.set_canvas(self.figurecanvas) 
     self.axe.clear() 
     self.figurecanvas.draw() 


class SubFrame(wx.Frame): 
    def __init__(self, parent, figure): 
     wx.Frame.__init__(self, parent, wx.NewId(), "Sub") 
     self.sizer = wx.BoxSizer(wx.VERTICAL) 
     self.figurecanvas = FigureCanvas(self, -1, figure) 
     self.sizer.Add(self.figurecanvas, proportion=1, border=5, flag=wx.ALL | wx.EXPAND) 
     self.SetSizer(self.sizer) 

     self.Bind(wx.EVT_CLOSE, self.on_close) 

    def on_close(self, evt): 
     self.GetParent().subframe_opened = False 
     evt.Skip() 



class MyApp(wx.App): 
    def OnInit(self): 
     frame = MainFrame() 
     frame.Show(True) 
     self.SetTopWindow(frame) 
     return True 

app = MyApp(0) 
app.MainLoop()  

내가 작업의 다음과 같은 순서에 관심이 있어요 :

  • 눌러 Plot 버튼
  • 더블 클릭 메인 프레임의 크기를 조정

    • 실행 스크립트 다음은 예입니다 플롯에서
    • 지우기 버튼을 누르십시오.

    이제 메인 프레임 그림이 엉망이되었습니다. 프레임 크기를 조정하면 제대로 다시 그립니다. 내 질문에 크기를 조정하지 않고 코드를 추가해야하는 이유는 무엇입니까? 사전에

    http://img227.imageshack.us/img227/5407/mess.png

    감사하십시오 "엉망"으로

    나는 같은 것을 의미한다.

  • +0

    @Alex, 나는 당신이 무엇을 요구하고 있는지 확실하지 않습니다. "엉망"이란 무엇을 의미합니까? 나는 당신의 코드를 시험해 보았고 어떤 문제도 보지 못했다. 메인 프레임 크기 조정 OK, 버튼 그리기 플롯, 더블 클릭으로 같은 그림 캔버스를 보여주는 새로운 프레임 생성, 지우기 버튼은 플롯을 지우고 서브 프레임을 닫습니다. – Mark

    +0

    흠 .. 이상 하네, 나는 Clear 후 상태로 그림을 추가했다. – Alex

    +0

    원래는 Linux에서 시도했지만 Windows에서는 사진을 재현 할 수 있습니다. 그것은 두 개의 wxFrames 사이에 그림 객체를 공유하기 때문입니다 (아마도 좋은 생각은 아닙니다). 아무도 그것에 나에게 베팅하지 않으면, 나는 오늘 저녁을 더 자세히 볼 것입니다. – Mark

    답변

    11

    내가 코멘트에서 말했듯이 그림 캔버스 새로 고침이 문제라고 생각하지 않습니다. 사실 그것이 정확히 무엇을하고 있다고 생각합니다 (마지막 상태에 따라 다시 그리기 [즉 당신의 subplot]). 귀하의 문제는 wxFrame이 상쾌하지 않다는 것 이상으로 생각합니다.

    가장 쉬운 방법은 "지우기"이벤트에서 자체 크기를 조정하는 것입니다. 다음과 같이 설정하십시오 :

    def on_button_clear(self, evt): 
        if self.subframe_opened: 
         self.subframe.Close() 
        self.figure.set_canvas(self.figurecanvas) 
        self.axe.clear() 
        self.figurecanvas.draw() 
        self.SetSize((self.Size[0],self.figurecanvas.Size[1])) 
    

    설정된 크기로 인해 프레임과 그 안에 포함 된 모든 컨트롤이 다시 그려집니다.

    그건 그렇고, 나는 두 figurecanvas 사이에 당신의 모습을 공유하는 것이 위험하다고 생각합니다. 다른 조합으로 클릭하거나 크기를 조정하여 심각한 오류를 생성 할 수있었습니다. 경우에 따라 서브 프레임이 닫힐 때 가비지 수집되어 메인 프레임에서 사용할 수 없게됩니다.

    +0

    크기 조정은 내 경우 사용자 친화적이지는 않지만 감사합니다. 내가 할 수있는 최선의 방법은 그림을 공유하지 않는 것입니다. – Alex

    +0

    'self.axe.clear()'가 매우 느립니다! 내 애플 리케이션, 나는 많은 시간을 줄거리가 필요합니다,'self.axe.clear()'는 0.5s 내 애플 리케이션을 걸 것이다 : ( –

    관련 문제