matplotlib in wx Frame, kein Zeichnen

Plattformunabhängige GUIs mit wxWidgets.
Antworten
joh#
User
Beiträge: 139
Registriert: Freitag 6. November 2009, 13:16

Hallo,

im folgenden möchte ich bei drücken des Buttons "Load X1"
self.data geplottet haben (im Moment nur dummies/random)
beim Aufbau der Oberfläche (__init__ . . . ) wird das auch gemacht
aber explizit bei Aufruf der on_analyze_button(self, event) Methode
nicht, obwohl self.data entspr. Daten enthält.

Gruß
joh


Code: Alles auswählen

from numpy import arange
import wxversion
wxversion.select("2.8")

import wx, sys, random
import matplotlib as mpl
mpl.use('WXAgg')

from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure

def make_dummy(length):
    '''returns a list of floats with length'''
    retval=[]
    random.seed()
    for i in xrange(length):
        retval.append(random.random())
    return retval



class CanvasPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

    def draw(self, dataY):
        self.axes.plot(dataY)


    

class GraphFrame(wx.Frame):
    """ The main frame of the application
    """
    title = ' plotdata '
    
    
    def __init__(self):
        wx.Frame.__init__(self, None, -1, title=self.title, pos=(50,50), size=(1200,600))
        self.create_main_panel()
        self.data = []
        
    def create_main_panel(self):
        self.panel = wx.Panel(self)
        
        self.loadQX_button = wx.Button(self.panel, -1, "Load X1")
        self.Bind(wx.EVT_BUTTON, self.on_loadQX_button, self.loadQX_button)
        
        self.analyze_button = wx.Button(self.panel, -1, "Analyze")
        self.Bind(wx.EVT_BUTTON, self.on_analyze_button, self.analyze_button)

        self.BoxSizerVButtons = wx.BoxSizer(wx.VERTICAL)
        self.BoxSizerH_Top = wx.BoxSizer(wx.HORIZONTAL) 
        
        self.BoxSizerVButtons.AddSpacer(20)
        self.BoxSizerVButtons.Add(self.loadQX_button)        
        self.BoxSizerVButtons.AddSpacer(20)
        self.BoxSizerVButtons.Add(self.analyze_button)
        self.BoxSizerVButtons.AddSpacer(20)
        
        

        self.subpanel = CanvasPanel(self.panel)
        nulldata = [0 for x in arange(1,1000)]
        self.subpanel.draw(nulldata)                
                      
                      
        
        self.BoxSizerH_Top.AddSpacer(20)
        self.BoxSizerH_Top.Add(self.BoxSizerVButtons)
        self.BoxSizerH_Top.AddSpacer(20)
        self.BoxSizerH_Top.Add(self.subpanel)
        self.panel.SetSizer(self.BoxSizerH_Top)
        self.BoxSizerH_Top.Fit(self)
        
     
    
    def on_loadQX_button(self, event):
        self.data = make_dummy(2000)
        self.MW = reduce(lambda x,y: x+y, self.data)/len(self.data)
    
    def on_analyze_button(self, event):
        self.subpanel.draw(self.data)    #
        #self.subpanel.draw([1 for x in arange(1,1000)])
    
    

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame=GraphFrame()
    frame.Show()
    app.MainLoop()
BlackJack

@joh#: So ganz grundsätzlich fehlt Dir ein `draw()`-Aufruf auf dem Canvas. Dann möchtest Du zusätzlich vielleicht noch den alten Inhalt vorher löschen.

`random.seed()` braucht man nicht aufrufen, man sollte es noch nicht einmal tun. Denn es kann in gewissen Fällen sogar dafür sorgen, dass die Pseudozufallszahlen *weniger* zufällig sind.

Du bindest auch ein bisschen viel an die Objekte. Man muss nicht blind vor jeden Namen in einer Methode ein ``self.`` schreiben, sondern nur bei solchen Namen, die auch tatsächlich den Zustand des Objekts ausmachen und die irgendwo aus einer anderen Methode oder von aussen noch verwendet werden müssen.

Code: Alles auswählen

#!/usr/bin/env python
from random import random
import matplotlib as mpl
mpl.use('WXAgg')
import wxversion
wxversion.select('2.8')
import wx
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure


def create_dummy_data(length):
    '''returns a list of floats with length'''
    return [random() for _ in xrange(length)]



class CanvasPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        figure = Figure()
        self.axes = figure.add_subplot(111)
        self.canvas = FigureCanvas(self, wx.ID_ANY, figure)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(sizer)
        self.Fit()

    def draw(self, data_y):
        self.axes.plot(data_y)
        self.canvas.draw()
    

class GraphFrame(wx.Frame):
    """The main frame of the application"""
    TITLE = ' plotdata '
    
    def __init__(self):
        wx.Frame.__init__(
            self,
            None,
            wx.ID_ANY,
            title=self.TITLE,
            pos=(50, 50),
            size=(1200, 600)
        )
        self.create_main_panel()
        self.data = list()
        
    def create_main_panel(self):
        panel = wx.Panel(self)
        
        load_qx_button = wx.Button(panel, wx.ID_ANY, 'Load X1')
        self.Bind(wx.EVT_BUTTON, self.on_load_qx_button, load_qx_button)
        
        analyze_button = wx.Button(panel, wx.ID_ANY, 'Analyze')
        self.Bind(wx.EVT_BUTTON, self.on_analyze_button, analyze_button)

        button_sizer = wx.BoxSizer(wx.VERTICAL)
        content_sizer = wx.BoxSizer(wx.HORIZONTAL) 
        
        button_sizer.AddSpacer(20)
        button_sizer.Add(load_qx_button)        
        button_sizer.AddSpacer(20)
        button_sizer.Add(analyze_button)
        button_sizer.AddSpacer(20)

        self.subpanel = CanvasPanel(panel)
        self.subpanel.draw([0] * 2000)                
        
        content_sizer.AddSpacer(20)
        content_sizer.Add(button_sizer)
        content_sizer.AddSpacer(20)
        content_sizer.Add(self.subpanel)
        panel.SetSizer(content_sizer)
        content_sizer.Fit(self)
    
    def on_load_qx_button(self, _event):
        self.data = create_dummy_data(2000)
    
    def on_analyze_button(self, _event):
        self.subpanel.draw(self.data)


def main():
    app = wx.PySimpleApp()
    frame = GraphFrame()
    frame.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()
joh#
User
Beiträge: 139
Registriert: Freitag 6. November 2009, 13:16

BlackJack hat geschrieben:@joh#: So ganz grundsätzlich fehlt Dir ein `draw()`-Aufruf auf dem Canvas.
Danke! Das war's
joh
Antworten