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()
raise ImportError
#
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:
'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):
'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)
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:
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)
+ wx.EVT_SIZE(self,self.reconfigure)
wx.EVT_PAINT(self, self.OnPaint)
- self._setsize()
- self.last_draw = None
-# self.font = self._testFont(font)
+ 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:
+ 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:
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')
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()
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)