]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/tests/wxPlotCanvas.py
wxPython Merge #2 of 2.4 branch --> HEAD (branch tag: wxPy_2_4_merge_2)
[wxWidgets.git] / wxPython / tests / wxPlotCanvas.py
diff --git a/wxPython/tests/wxPlotCanvas.py b/wxPython/tests/wxPlotCanvas.py
deleted file mode 100644 (file)
index c65e701..0000000
+++ /dev/null
@@ -1,459 +0,0 @@
-"""
-This is a port of Konrad Hinsen's tkPlotCanvas.py plotting module.
-After thinking long and hard I came up with the name "wxPlotCanvas.py".
-
-This file contains two parts; first the re-usable library stuff, then, after
-a "if __name__=='__main__'" test, a simple frame and a few default plots
-for testing.
-
-Harm van der Heijden, feb 1999
-
-Original comment follows below:
-# This module defines a plot widget for Tk user interfaces.
-# It supports only elementary line plots at the moment.
-# See the example at the end for documentation...
-#
-# Written by Konrad Hinsen <hinsen@cnrs-orleans.fr>
-# With contributions from RajGopal Srinivasan <raj@cherubino.med.jhmi.edu>
-# Last revision: 1998-7-28
-#
-"""
-
-from wxPython import wx
-
-# Not everybody will have Numeric, so let's be cool about it...
-try:
-    import Numeric
-except:
-    # bummer!
-    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.""",
-    "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()
-    import sys
-    sys.exit()
-
-#
-# Plotting classes...
-#
-class PolyPoints:
-
-    def __init__(self, points, attr):
-        self.points = Numeric.array(points)
-        self.scaled = self.points
-        self.attributes = {}
-        for name, value in self._attributes.items():
-            try:
-                value = attr[name]
-            except KeyError: pass
-            self.attributes[name] = value
-
-    def boundingBox(self):
-        return Numeric.minimum.reduce(self.points), \
-               Numeric.maximum.reduce(self.points)
-
-    def scaleAndShift(self, scale=1, shift=0):
-        self.scaled = scale*self.points+shift
-
-
-class PolyLine(PolyPoints):
-
-    def __init__(self, points, **attr):
-        PolyPoints.__init__(self, points, attr)
-
-    _attributes = {'color': 'black',
-                   '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))
-
-
-class PolyMarker(PolyPoints):
-
-    def __init__(self, points, **attr):
-
-        PolyPoints.__init__(self, points, attr)
-
-    _attributes = {'color': 'black',
-                   'width': 1,
-                   'fillcolor': None,
-                   'size': 2,
-                   'fillstyle': wx.wxSOLID,
-                   'outline': 'black',
-                   'marker': 'circle'}
-
-    def draw(self, dc):
-        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))
-
-        self._drawmarkers(dc, self.scaled, marker, size)
-
-    def _drawmarkers(self, dc, coords, marker,size=1):
-        f = eval('self._' +marker)
-        for xc, yc in coords:
-            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)
-
-    def _dot(self, dc, xc, yc, size=1):
-        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)
-
-    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)
-
-    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)
-
-    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)
-
-    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)
-
-class PlotGraphics:
-
-    def __init__(self, objects):
-        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
-
-    def scaleAndShift(self, scale=1, shift=0):
-        for o in self.objects:
-            o.scaleAndShift(scale, shift)
-
-    def draw(self, canvas):
-        for o in self.objects:
-            o.draw(canvas)
-
-    def __len__(self):
-        return len(self.objects)
-
-    def __getitem__(self, 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.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,))
-
-    def reconfigure(self, event):
-        (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
-
-    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])
-
-    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,
-                       scale, shift, xticks, yticks)
-        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'
-
-    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
-
-    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
-        if power > 3 or power < -3:
-            format = '%+7.0e'
-        elif power >= 0:
-            digits = max(1, int(power))
-            format = '%' + `digits`+'.0f'
-        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
-
-    _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,))
-
-    def clear(self):
-        self.canvas.delete('all')
-
-#
-# Now a sample implementation using the above...
-#
-
-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,
-"""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)
-
-        def OnFileExit(self, event):
-            self.Close()
-
-        def OnPlotDraw(self, event):
-            self.client.draw(InitObjects(),'automatic','automatic');
-
-        def OnPlotRedraw(self,event):
-            self.client.redraw()
-
-        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 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)
-
-        # 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')
-
-        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
-
-
-    app = MyApp(0)
-    app.MainLoop()