X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f6bcfd974ef26faf6f91a62cac09827e09463fd1..0cf5de11339b7ee3cb3550fbac3927eaaa238d4f:/wxPython/tests/wxPlotCanvas.py?ds=inline diff --git a/wxPython/tests/wxPlotCanvas.py b/wxPython/tests/wxPlotCanvas.py index baa9112c10..c65e7011fb 100644 --- a/wxPython/tests/wxPlotCanvas.py +++ b/wxPython/tests/wxPlotCanvas.py @@ -20,22 +20,21 @@ Original comment follows below: """ from wxPython import wx -import string # Not everybody will have Numeric, so let's be cool about it... try: import Numeric except: # bummer! - d = wx.wxMessageDialog(wx.NULL, + d = wx.wxMessageDialog(wx.NULL, """This module requires the Numeric module, which could not be imported. It probably is not installed (it's not part of the standard Python -distribution). See the Python site (http://www.python.org) for -information on downloading source or binaries.""", +distribution). See the Python site (http://www.python.org) for +information on downloading source or binaries.""", "Numeric not found") if d.ShowModal() == wx.wxID_CANCEL: - d = wx.wxMessageDialog(wx.NULL, "I kid you not! Pressing Cancel won't help you!", "Not a joke", wx.wxOK) - d.ShowModal() + d = wx.wxMessageDialog(wx.NULL, "I kid you not! Pressing Cancel won't help you!", "Not a joke", wx.wxOK) + d.ShowModal() import sys sys.exit() @@ -46,7 +45,7 @@ class PolyPoints: def __init__(self, points, attr): self.points = Numeric.array(points) - self.scaled = self.points + self.scaled = self.points self.attributes = {} for name, value in self._attributes.items(): try: @@ -71,11 +70,11 @@ class PolyLine(PolyPoints): 'width': 1} def draw(self, dc): - color = self.attributes['color'] - width = self.attributes['width'] - arguments = [] - dc.SetPen(wx.wxPen(wx.wxNamedColour(color), width)) - dc.DrawLines(map(tuple,self.scaled)) + color = self.attributes['color'] + width = self.attributes['width'] + arguments = [] + dc.SetPen(wx.wxPen(wx.wxNamedColour(color), width)) + dc.DrawLines(map(tuple,self.scaled)) class PolyMarker(PolyPoints): @@ -88,25 +87,25 @@ class PolyMarker(PolyPoints): 'width': 1, 'fillcolor': None, 'size': 2, - 'fillstyle': wx.wxSOLID, + 'fillstyle': wx.wxSOLID, 'outline': 'black', 'marker': 'circle'} def draw(self, dc): - color = self.attributes['color'] - width = self.attributes['width'] + color = self.attributes['color'] + width = self.attributes['width'] size = self.attributes['size'] fillcolor = self.attributes['fillcolor'] fillstyle = self.attributes['fillstyle'] marker = self.attributes['marker'] - dc.SetPen(wx.wxPen(wx.wxNamedColour(color),width)) - if fillcolor: - dc.SetBrush(wx.wxBrush(wx.wxNamedColour(fillcolor),fillstyle)) - else: - dc.SetBrush(wx.wxBrush(wx.wxNamedColour('black'), wx.wxTRANSPARENT)) + dc.SetPen(wx.wxPen(wx.wxNamedColour(color),width)) + if fillcolor: + dc.SetBrush(wx.wxBrush(wx.wxNamedColour(fillcolor),fillstyle)) + else: + dc.SetBrush(wx.wxBrush(wx.wxNamedColour('black'), wx.wxTRANSPARENT)) - self._drawmarkers(dc, self.scaled, marker, size) + self._drawmarkers(dc, self.scaled, marker, size) def _drawmarkers(self, dc, coords, marker,size=1): f = eval('self._' +marker) @@ -114,31 +113,31 @@ class PolyMarker(PolyPoints): f(dc, xc, yc, size) def _circle(self, dc, xc, yc, size=1): - dc.DrawEllipse(xc-2.5*size,yc-2.5*size,5.*size,5.*size) + dc.DrawEllipse(xc-2.5*size,yc-2.5*size,5.*size,5.*size) def _dot(self, dc, xc, yc, size=1): - dc.DrawPoint(xc,yc) + dc.DrawPoint(xc,yc) def _square(self, dc, xc, yc, size=1): - dc.DrawRectangle(xc-2.5*size,yc-2.5*size,5.*size,5.*size) - + dc.DrawRectangle(xc-2.5*size,yc-2.5*size,5.*size,5.*size) + def _triangle(self, dc, xc, yc, size=1): - dc.DrawPolygon([(-0.5*size*5,0.2886751*size*5), - (0.5*size*5,0.2886751*size*5), - (0.0,-0.577350*size*5)],xc,yc) + dc.DrawPolygon([(-0.5*size*5,0.2886751*size*5), + (0.5*size*5,0.2886751*size*5), + (0.0,-0.577350*size*5)],xc,yc) def _triangle_down(self, dc, xc, yc, size=1): - dc.DrawPolygon([(-0.5*size*5,-0.2886751*size*5), - (0.5*size*5,-0.2886751*size*5), - (0.0,0.577350*size*5)],xc,yc) + dc.DrawPolygon([(-0.5*size*5,-0.2886751*size*5), + (0.5*size*5,-0.2886751*size*5), + (0.0,0.577350*size*5)],xc,yc) def _cross(self, dc, xc, yc, size=1): - dc.DrawLine(xc-2.5*size,yc-2.5*size,xc+2.5*size,yc+2.5*size) - dc.DrawLine(xc-2.5*size,yc+2.5*size,xc+2.5*size,yc-2.5*size) + dc.DrawLine(xc-2.5*size,yc-2.5*size,xc+2.5*size,yc+2.5*size) + dc.DrawLine(xc-2.5*size,yc+2.5*size,xc+2.5*size,yc-2.5*size) def _plus(self, dc, xc, yc, size=1): - dc.DrawLine(xc-2.5*size,yc,xc+2.5*size,yc) - dc.DrawLine(xc,yc-2.5*size,xc,yc+2.5*size) + dc.DrawLine(xc-2.5*size,yc,xc+2.5*size,yc) + dc.DrawLine(xc,yc-2.5*size,xc,yc+2.5*size) class PlotGraphics: @@ -146,191 +145,191 @@ class PlotGraphics: self.objects = objects def boundingBox(self): - p1, p2 = self.objects[0].boundingBox() - for o in self.objects[1:]: - p1o, p2o = o.boundingBox() - p1 = Numeric.minimum(p1, p1o) - p2 = Numeric.maximum(p2, p2o) - return p1, p2 + p1, p2 = self.objects[0].boundingBox() + for o in self.objects[1:]: + p1o, p2o = o.boundingBox() + p1 = Numeric.minimum(p1, p1o) + p2 = Numeric.maximum(p2, p2o) + return p1, p2 def scaleAndShift(self, scale=1, shift=0): - for o in self.objects: - o.scaleAndShift(scale, shift) + for o in self.objects: + o.scaleAndShift(scale, shift) def draw(self, canvas): - for o in self.objects: - o.draw(canvas) + for o in self.objects: + o.draw(canvas) def __len__(self): - return len(self.objects) + return len(self.objects) def __getitem__(self, item): - return self.objects[item] + return self.objects[item] class PlotCanvas(wx.wxWindow): def __init__(self, parent, id = -1): - wx.wxWindow.__init__(self, parent, id, wx.wxPyDefaultPosition, wx.wxPyDefaultSize) - self.border = (1,1) - self.SetClientSizeWH(400,400) - self.SetBackgroundColour(wx.wxNamedColour("white")) + wx.wxWindow.__init__(self, parent, id, wx.wxPyDefaultPosition, wx.wxPyDefaultSize) + self.border = (1,1) + self.SetClientSizeWH(400,400) + self.SetBackgroundColour(wx.wxNamedColour("white")) - wx.EVT_SIZE(self,self.reconfigure) - self._setsize() - self.last_draw = None -# self.font = self._testFont(font) + wx.EVT_SIZE(self,self.reconfigure) + self._setsize() + self.last_draw = None +# self.font = self._testFont(font) def OnPaint(self, event): - pdc = wx.wxPaintDC(self) - if self.last_draw is not None: - apply(self.draw, self.last_draw + (pdc,)) + pdc = wx.wxPaintDC(self) + if self.last_draw is not None: + apply(self.draw, self.last_draw + (pdc,)) def reconfigure(self, event): - (new_width,new_height) = self.GetClientSizeTuple() + (new_width,new_height) = self.GetClientSizeTuple() if new_width == self.width and new_height == self.height: return self._setsize() # self.redraw() def _testFont(self, font): - if font is not None: - bg = self.canvas.cget('background') - try: - item = CanvasText(self.canvas, 0, 0, anchor=NW, - text='0', fill=bg, font=font) - self.canvas.delete(item) - except TclError: - font = None - return font + if font is not None: + bg = self.canvas.cget('background') + try: + item = CanvasText(self.canvas, 0, 0, anchor=NW, + text='0', fill=bg, font=font) + self.canvas.delete(item) + except TclError: + font = None + return font def _setsize(self): - (self.width,self.height) = self.GetClientSizeTuple(); - self.plotbox_size = 0.97*Numeric.array([self.width, -self.height]) - xo = 0.5*(self.width-self.plotbox_size[0]) - yo = self.height-0.5*(self.height+self.plotbox_size[1]) - self.plotbox_origin = Numeric.array([xo, yo]) + (self.width,self.height) = self.GetClientSizeTuple(); + self.plotbox_size = 0.97*Numeric.array([self.width, -self.height]) + xo = 0.5*(self.width-self.plotbox_size[0]) + yo = self.height-0.5*(self.height+self.plotbox_size[1]) + self.plotbox_origin = Numeric.array([xo, yo]) def draw(self, graphics, xaxis = None, yaxis = None, dc = None): - if dc == None: dc = wx.wxClientDC(self) - dc.BeginDrawing() - dc.Clear() - self.last_draw = (graphics, xaxis, yaxis) - p1, p2 = graphics.boundingBox() - xaxis = self._axisInterval(xaxis, p1[0], p2[0]) - yaxis = self._axisInterval(yaxis, p1[1], p2[1]) - text_width = [0., 0.] - text_height = [0., 0.] - if xaxis is not None: - p1[0] = xaxis[0] - p2[0] = xaxis[1] - xticks = self._ticks(xaxis[0], xaxis[1]) - bb = dc.GetTextExtent(xticks[0][1]) - text_height[1] = bb[1] - text_width[0] = 0.5*bb[0] - bb = dc.GetTextExtent(xticks[-1][1]) - text_width[1] = 0.5*bb[0] - else: - xticks = None - if yaxis is not None: - p1[1] = yaxis[0] - p2[1] = yaxis[1] - yticks = self._ticks(yaxis[0], yaxis[1]) - for y in yticks: - bb = dc.GetTextExtent(y[1]) - text_width[0] = max(text_width[0],bb[0]) - h = 0.5*bb[1] - text_height[0] = h - text_height[1] = max(text_height[1], h) - else: - yticks = None - text1 = Numeric.array([text_width[0], -text_height[1]]) - text2 = Numeric.array([text_width[1], -text_height[0]]) - scale = (self.plotbox_size-text1-text2) / (p2-p1) - shift = -p1*scale + self.plotbox_origin + text1 - self._drawAxes(dc, xaxis, yaxis, p1, p2, + if dc == None: dc = wx.wxClientDC(self) + dc.BeginDrawing() + dc.Clear() + self.last_draw = (graphics, xaxis, yaxis) + p1, p2 = graphics.boundingBox() + xaxis = self._axisInterval(xaxis, p1[0], p2[0]) + yaxis = self._axisInterval(yaxis, p1[1], p2[1]) + text_width = [0., 0.] + text_height = [0., 0.] + if xaxis is not None: + p1[0] = xaxis[0] + p2[0] = xaxis[1] + xticks = self._ticks(xaxis[0], xaxis[1]) + bb = dc.GetTextExtent(xticks[0][1]) + text_height[1] = bb[1] + text_width[0] = 0.5*bb[0] + bb = dc.GetTextExtent(xticks[-1][1]) + text_width[1] = 0.5*bb[0] + else: + xticks = None + if yaxis is not None: + p1[1] = yaxis[0] + p2[1] = yaxis[1] + yticks = self._ticks(yaxis[0], yaxis[1]) + for y in yticks: + bb = dc.GetTextExtent(y[1]) + text_width[0] = max(text_width[0],bb[0]) + h = 0.5*bb[1] + text_height[0] = h + text_height[1] = max(text_height[1], h) + else: + yticks = None + text1 = Numeric.array([text_width[0], -text_height[1]]) + text2 = Numeric.array([text_width[1], -text_height[0]]) + scale = (self.plotbox_size-text1-text2) / (p2-p1) + shift = -p1*scale + self.plotbox_origin + text1 + self._drawAxes(dc, xaxis, yaxis, p1, p2, scale, shift, xticks, yticks) - graphics.scaleAndShift(scale, shift) - graphics.draw(dc) - dc.EndDrawing() + graphics.scaleAndShift(scale, shift) + graphics.draw(dc) + dc.EndDrawing() def _axisInterval(self, spec, lower, upper): - if spec is None: - return None - if spec == 'minimal': - if lower == upper: - return lower-0.5, upper+0.5 - else: - return lower, upper - if spec == 'automatic': - range = upper-lower - if range == 0.: - return lower-0.5, upper+0.5 - log = Numeric.log10(range) - power = Numeric.floor(log) - fraction = log-power - if fraction <= 0.05: - power = power-1 - grid = 10.**power - lower = lower - lower % grid - mod = upper % grid - if mod != 0: - upper = upper - mod + grid - return lower, upper - if type(spec) == type(()): - lower, upper = spec - if lower <= upper: - return lower, upper - else: - return upper, lower - raise ValueError, str(spec) + ': illegal axis specification' + if spec is None: + return None + if spec == 'minimal': + if lower == upper: + return lower-0.5, upper+0.5 + else: + return lower, upper + if spec == 'automatic': + range = upper-lower + if range == 0.: + return lower-0.5, upper+0.5 + log = Numeric.log10(range) + power = Numeric.floor(log) + fraction = log-power + if fraction <= 0.05: + power = power-1 + grid = 10.**power + lower = lower - lower % grid + mod = upper % grid + if mod != 0: + upper = upper - mod + grid + return lower, upper + if type(spec) == type(()): + lower, upper = spec + if lower <= upper: + return lower, upper + else: + return upper, lower + raise ValueError, str(spec) + ': illegal axis specification' def _drawAxes(self, dc, xaxis, yaxis, bb1, bb2, scale, shift, xticks, yticks): - dc.SetPen(wx.wxPen(wx.wxNamedColour('BLACK'),1)) - if xaxis is not None: - lower, upper = xaxis - text = 1 - for y, d in [(bb1[1], -3), (bb2[1], 3)]: - p1 = scale*Numeric.array([lower, y])+shift - p2 = scale*Numeric.array([upper, y])+shift - dc.DrawLine(p1[0],p1[1],p2[0],p2[1]) - for x, label in xticks: - p = scale*Numeric.array([x, y])+shift - dc.DrawLine(p[0],p[1],p[0],p[1]+d) - if text: - dc.DrawText(label,p[0],p[1]) - text = 0 - - if yaxis is not None: - lower, upper = yaxis - text = 1 - h = dc.GetCharHeight() - for x, d in [(bb1[0], -3), (bb2[0], 3)]: - p1 = scale*Numeric.array([x, lower])+shift - p2 = scale*Numeric.array([x, upper])+shift - dc.DrawLine(p1[0],p1[1],p2[0],p2[1]) - for y, label in yticks: - p = scale*Numeric.array([x, y])+shift - dc.DrawLine(p[0],p[1],p[0]-d,p[1]) - if text: - dc.DrawText(label,p[0]-dc.GetTextExtent(label)[0], - p[1]-0.5*h) - text = 0 + dc.SetPen(wx.wxPen(wx.wxNamedColour('BLACK'),1)) + if xaxis is not None: + lower, upper = xaxis + text = 1 + for y, d in [(bb1[1], -3), (bb2[1], 3)]: + p1 = scale*Numeric.array([lower, y])+shift + p2 = scale*Numeric.array([upper, y])+shift + dc.DrawLine(p1[0],p1[1],p2[0],p2[1]) + for x, label in xticks: + p = scale*Numeric.array([x, y])+shift + dc.DrawLine(p[0],p[1],p[0],p[1]+d) + if text: + dc.DrawText(label,p[0],p[1]) + text = 0 + + if yaxis is not None: + lower, upper = yaxis + text = 1 + h = dc.GetCharHeight() + for x, d in [(bb1[0], -3), (bb2[0], 3)]: + p1 = scale*Numeric.array([x, lower])+shift + p2 = scale*Numeric.array([x, upper])+shift + dc.DrawLine(p1[0],p1[1],p2[0],p2[1]) + for y, label in yticks: + p = scale*Numeric.array([x, y])+shift + dc.DrawLine(p[0],p[1],p[0]-d,p[1]) + if text: + dc.DrawText(label,p[0]-dc.GetTextExtent(label)[0], + p[1]-0.5*h) + text = 0 def _ticks(self, lower, upper): - ideal = (upper-lower)/7. - log = Numeric.log10(ideal) - power = Numeric.floor(log) - fraction = log-power - factor = 1. - error = fraction - for f, lf in self._multiples: - e = Numeric.fabs(fraction-lf) - if e < error: - error = e - factor = f - grid = factor * 10.**power + ideal = (upper-lower)/7. + log = Numeric.log10(ideal) + power = Numeric.floor(log) + fraction = log-power + factor = 1. + error = fraction + for f, lf in self._multiples: + e = Numeric.fabs(fraction-lf) + if e < error: + error = e + factor = f + grid = factor * 10.**power if power > 3 or power < -3: format = '%+7.0e' elif power >= 0: @@ -339,18 +338,18 @@ class PlotCanvas(wx.wxWindow): else: digits = -int(power) format = '%'+`digits+2`+'.'+`digits`+'f' - ticks = [] - t = -grid*Numeric.floor(-lower/grid) - while t <= upper: - ticks.append(t, format % (t,)) - t = t + grid - return ticks + ticks = [] + t = -grid*Numeric.floor(-lower/grid) + while t <= upper: + ticks.append(t, format % (t,)) + t = t + grid + return ticks _multiples = [(2., Numeric.log10(2.)), (5., Numeric.log10(5.))] def redraw(self,dc=None): - if self.last_draw is not None: - apply(self.draw, self.last_draw + (dc,)) + if self.last_draw is not None: + apply(self.draw, self.last_draw + (dc,)) def clear(self): self.canvas.delete('all') @@ -362,98 +361,98 @@ class PlotCanvas(wx.wxWindow): if __name__ == '__main__': class AppFrame(wx.wxFrame): - def __init__(self, parent, id, title): - wx.wxFrame.__init__(self, parent, id, title, - wx.wxPyDefaultPosition, wx.wxSize(400, 400)) - - # Now Create the menu bar and items - self.mainmenu = wx.wxMenuBar() - - menu = wx.wxMenu() - menu.Append(200, '&Print...', 'Print the current plot') - wx.EVT_MENU(self, 200, self.OnFilePrint) - menu.Append(209, 'E&xit', 'Enough of this already!') - wx.EVT_MENU(self, 209, self.OnFileExit) - self.mainmenu.Append(menu, '&File') - - menu = wx.wxMenu() - menu.Append(210, '&Draw', 'Draw plots') - wx.EVT_MENU(self,210,self.OnPlotDraw) - menu.Append(211, '&Redraw', 'Redraw plots') - wx.EVT_MENU(self,211,self.OnPlotRedraw) - menu.Append(212, '&Clear', 'Clear canvas') - wx.EVT_MENU(self,212,self.OnPlotClear) - self.mainmenu.Append(menu, '&Plot') - - menu = wx.wxMenu() - menu.Append(220, '&About', 'About this thing...') - wx.EVT_MENU(self, 220, self.OnHelpAbout) - self.mainmenu.Append(menu, '&Help') - - self.SetMenuBar(self.mainmenu) - - # A status bar to tell people what's happening - self.CreateStatusBar(1) - - self.client = PlotCanvas(self) - - def OnFilePrint(self, event): - d = wx.wxMessageDialog(self, + def __init__(self, parent, id, title): + wx.wxFrame.__init__(self, parent, id, title, + wx.wxPyDefaultPosition, wx.wxSize(400, 400)) + + # Now Create the menu bar and items + self.mainmenu = wx.wxMenuBar() + + menu = wx.wxMenu() + menu.Append(200, '&Print...', 'Print the current plot') + wx.EVT_MENU(self, 200, self.OnFilePrint) + menu.Append(209, 'E&xit', 'Enough of this already!') + wx.EVT_MENU(self, 209, self.OnFileExit) + self.mainmenu.Append(menu, '&File') + + menu = wx.wxMenu() + menu.Append(210, '&Draw', 'Draw plots') + wx.EVT_MENU(self,210,self.OnPlotDraw) + menu.Append(211, '&Redraw', 'Redraw plots') + wx.EVT_MENU(self,211,self.OnPlotRedraw) + menu.Append(212, '&Clear', 'Clear canvas') + wx.EVT_MENU(self,212,self.OnPlotClear) + self.mainmenu.Append(menu, '&Plot') + + menu = wx.wxMenu() + menu.Append(220, '&About', 'About this thing...') + wx.EVT_MENU(self, 220, self.OnHelpAbout) + self.mainmenu.Append(menu, '&Help') + + self.SetMenuBar(self.mainmenu) + + # A status bar to tell people what's happening + self.CreateStatusBar(1) + + self.client = PlotCanvas(self) + + def OnFilePrint(self, event): + d = wx.wxMessageDialog(self, """As of this writing, printing support in wxPython is shaky at best. Are you sure you want to do this?""", "Danger!", wx.wxYES_NO) if d.ShowModal() == wx.wxID_YES: - psdc = wx.wxPostScriptDC("out.ps", wx.TRUE, self) - self.client.redraw(psdc) + psdc = wx.wxPostScriptDC("out.ps", wx.TRUE, self) + self.client.redraw(psdc) - def OnFileExit(self, event): - self.Close() + def OnFileExit(self, event): + self.Close() - def OnPlotDraw(self, event): - self.client.draw(InitObjects(),'automatic','automatic'); + def OnPlotDraw(self, event): + self.client.draw(InitObjects(),'automatic','automatic'); - def OnPlotRedraw(self,event): - self.client.redraw() + def OnPlotRedraw(self,event): + self.client.redraw() - def OnPlotClear(self,event): - self.client.last_draw = None - dc = wx.wxClientDC(self.client) - dc.Clear() + def OnPlotClear(self,event): + self.client.last_draw = None + dc = wx.wxClientDC(self.client) + dc.Clear() - def OnHelpAbout(self, event): - about = wx.wxMessageDialog(self, __doc__, "About...", wx.wxOK) - about.ShowModal() + def OnHelpAbout(self, event): + about = wx.wxMessageDialog(self, __doc__, "About...", wx.wxOK) + about.ShowModal() - def OnCloseWindow(self, event): - self.Destroy() + def OnCloseWindow(self, event): + self.Destroy() def InitObjects(): - # 100 points sin function, plotted as green circles - data1 = 2.*Numeric.pi*Numeric.arange(200)/200. - data1.shape = (100, 2) - data1[:,1] = Numeric.sin(data1[:,0]) - markers1 = PolyMarker(data1, color='green', marker='circle',size=1) + # 100 points sin function, plotted as green circles + data1 = 2.*Numeric.pi*Numeric.arange(200)/200. + data1.shape = (100, 2) + data1[:,1] = Numeric.sin(data1[:,0]) + markers1 = PolyMarker(data1, color='green', marker='circle',size=1) - # 50 points cos function, plotted as red line - data1 = 2.*Numeric.pi*Numeric.arange(100)/100. - data1.shape = (50,2) - data1[:,1] = Numeric.cos(data1[:,0]) - lines = PolyLine(data1, color='red') + # 50 points cos function, plotted as red line + data1 = 2.*Numeric.pi*Numeric.arange(100)/100. + data1.shape = (50,2) + data1[:,1] = Numeric.cos(data1[:,0]) + lines = PolyLine(data1, color='red') - # A few more points... - pi = Numeric.pi - markers2 = PolyMarker([(0., 0.), (pi/4., 1.), (pi/2, 0.), - (3.*pi/4., -1)], color='blue', - fillcolor='green', marker='cross') + # A few more points... + pi = Numeric.pi + markers2 = PolyMarker([(0., 0.), (pi/4., 1.), (pi/2, 0.), + (3.*pi/4., -1)], color='blue', + fillcolor='green', marker='cross') - return PlotGraphics([markers1, lines, markers2]) + return PlotGraphics([markers1, lines, markers2]) class MyApp(wx.wxApp): - def OnInit(self): - frame = AppFrame(wx.NULL, -1, "wxPlotCanvas") - frame.Show(wx.TRUE) - self.SetTopWindow(frame) - return wx.TRUE + def OnInit(self): + frame = AppFrame(wx.NULL, -1, "wxPlotCanvas") + frame.Show(wx.TRUE) + self.SetTopWindow(frame) + return wx.TRUE app = MyApp(0)