matplotlib: как обновить figure.canvas - PullRequest
15 голосов
/ 14 марта 2010

Я не могу понять, как обновить экземпляр FigureCanvasWxAgg. Вот пример:


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

Заранее спасибо.

1 Ответ

12 голосов
/ 17 марта 2010

Как я уже говорил в комментариях, я не думаю, что обновление холста рисунка является вашей проблемой, на самом деле я думаю, что он делает именно то, что должен (перерисовывает себя, основываясь на своем последнем состоянии [т.е. подзаговор]). Я думаю, что ваша проблема в том, что 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]))

Заданный размер приведет к перерисовке кадра и всех элементов управления, которые в нем содержатся.

Тем не менее, я думаю, что разделение вашей фигуры между двумя фигурными холстами опасно. Я смог выдать несколько серьезных ошибок, нажав / изменив размеры в разных комбинациях. Иногда ваша фигура будет собираться мусором, когда подрамник будет закрыт, что сделает его недоступным для вашего основного кадра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...