Seite 1 von 1

Beispiel: wxPython Liniendiagramm

Verfasst: Samstag 16. Februar 2008, 15:20
von gerold
Dieses Beispiel soll eine Möglichkeit aufzeigen, wie man mit wxPython ein Liniendiagramm erstellen kann.

Bild

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import wx
import wx.lib.plot as plot


wx.SetDefaultPyEncoding("iso-8859-15")


class MyFrame(wx.Frame):
   
    def __init__(
        self, parent = None, id = -1, title = "Example", size = wx.Size(500, 500)
    ):
        wx.Frame.__init__(self, parent, id, title, size = size)
       
        panel = wx.Panel(self)
       
        vbox_main = wx.BoxSizer(wx.VERTICAL)
        panel.SetSizer(vbox_main)
       
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox_main.Add(vbox, 1, wx.ALL | wx.EXPAND, 5)
       
        canvas = plot.PlotCanvas(panel)
        vbox.Add(canvas, 1, wx.EXPAND | wx.ALL, 5)
       
        coordinates1 = (
            (1, 50), (2, 60), (3, 45), (4, 60), (5, 33), (6, 79),
        )
        coordinates2 = (
            (1, 40), (2, 30), (3, 65), (4, 80), (5, 23), (6, 19),
        )
        lines = (
            plot.PolyLine(
                coordinates1, colour = "green", legend = u" Jänner", width = 1
            ),
            plot.PolyLine(
                coordinates2, colour = "blue", legend = u" Februar", width = 1
            ),
        )
       
        graphics = plot.PlotGraphics(
            objects = lines, title = u"Monatsübersicht", xLabel = u"Monate",
            yLabel = u"Anzahl Verkäufe"
        )
       
        canvas.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.NORMAL))
        canvas.SetFontSizeAxis(10)
        canvas.SetFontSizeLegend(7)
        canvas.SetEnableLegend(True)
        canvas.SetXSpec('auto')
        canvas.SetYSpec('auto')
        canvas.SetEnableGrid(True)
       
        canvas.Draw(graphics, xAxis = (0, 12), yAxis = (0, 100))
        #canvas.Draw(graphics)


def main():
    """Testing"""
   
    app = wx.PySimpleApp()
    f = MyFrame()
    f.Center()
    f.Show()
    app.MainLoop()


if __name__ == "__main__":
    main()
mfg
Gerold
:-)

Stichworte: Diagramm Graph Linie Liniendiagramm

Verfasst: Sonntag 17. Februar 2008, 17:36
von gerold
xxx schrieb:
> würde nur gerne jetzt die
> SetEnablePointLabel Funktion von PlotCanvas aktivieren

Hallo xxx!

---------------
Bitte stelle deine Fragen im Python-Forum und nicht per Email. Wenn du per Email oder PN fragst, dann verpufft die Antwort und niemand außer dir kann davon profitieren.
---------------

Schau dir die Datei "plot.py" an. Du musst mit ``SetPointLabelFunc`` auf eine Funktion zeigen, die direkt in den DC des Canvas zeichnet. Im Beispiel, das in "plot.py" mit drinnen ist, macht das die Funktion ``DrawPointLabel``. Diese kannst du als Beispiel heranziehen.

mfg
Gerold
:-)

Script mit Label Funktion

Verfasst: Sonntag 17. Februar 2008, 19:13
von rkager
Habe die Datei etwas erweitert, es wird nun der Aktuelle Cursor Wert der einzelnen Linien angezeigt.
Die neuen Zeilen wurden aus plot.py vom wx Paket eingefügt.

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-

import wx
import wx.lib.plot as plot


wx.SetDefaultPyEncoding("iso-8859-15")


class MyFrame(wx.Frame):
   
    def __init__(
        self, parent = None, id = -1, title = "Example", size = wx.Size(500, 500)
    ):
        wx.Frame.__init__(self, parent, id, title, size = size)
       
        panel = wx.Panel(self)
       
        vbox_main = wx.BoxSizer(wx.VERTICAL)
        panel.SetSizer(vbox_main)        
       
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox_main.Add(vbox, 1, wx.ALL | wx.EXPAND, 5)
       
        self.client = plot.PlotCanvas(panel)

        ##new declarations
        
        #define the function for drawing pointLabels
        self.client.SetPointLabelFunc(self.DrawPointLabel)
        # Create mouse event for showing cursor coords in status bar
        self.client.canvas.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
        # Show closest point when enabled
        self.client.canvas.Bind(wx.EVT_MOTION, self.OnMotion)
        ##end of new declarations

        
        vbox.Add(self.client, 1, wx.EXPAND | wx.ALL, 5)

        
       
        coordinates1 = (
            (1, 50), (2, 60), (3, 45), (4, 60), (5, 33), (6, 79),
        )
        coordinates2 = (
            (1, 40), (2, 30), (3, 65), (4, 80), (5, 23), (6, 19),
        )
        lines = (
            plot.PolyLine(
                coordinates1, colour = "green", legend = u" Jänner", width = 1
            ),
            plot.PolyLine(
                coordinates2, colour = "blue", legend = u" Februar", width = 1
            ),
        )
       
        graphics = plot.PlotGraphics(
            objects = lines, title = u"Monatsübersicht", xLabel = u"Monate",
            yLabel = u"Anzahl Verkäufe"
        )
       
        self.client.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.NORMAL))
        self.client.SetFontSizeAxis(10)
        self.client.SetFontSizeLegend(7)
        self.client.SetEnableLegend(True)
        self.client.SetXSpec('auto')
        self.client.SetYSpec('auto')
        self.client.SetEnableGrid(True)

        ##Activate Labels        
        self.client.SetEnablePointLabel(True)
       
        self.client.Draw(graphics)

        ##show Statusbar for Mouse Position
        self.CreateStatusBar(1)        


    ##Functions from plot.py
    def DrawPointLabel(self, dc, mDataDict):
        """This is the fuction that defines how the pointLabels are plotted
            dc - DC that will be passed
            mDataDict - Dictionary of data that you want to use for the pointLabel

            As an example I have decided I want a box at the curve point
            with some text information about the curve plotted below.
            Any wxDC method can be used.
        """
        # ----------
        dc.SetPen(wx.Pen(wx.BLACK))
        dc.SetBrush(wx.Brush( wx.BLACK, wx.SOLID ) )
        
        sx, sy = mDataDict["scaledXY"] #scaled x,y of closest point
        dc.DrawRectangle( sx-5,sy-5, 10, 10)  #10by10 square centered on point
        px,py = mDataDict["pointXY"]
        cNum = mDataDict["curveNum"]
        pntIn = mDataDict["pIndex"]
        legend = mDataDict["legend"]
        #make a string to display
        s = "Crv# %i, '%s', Pt. (%.2f,%.2f), PtInd %i" %(cNum, legend, px, py, pntIn)
        dc.DrawText(s, sx , sy+1)
        # -----------

    def OnMouseLeftDown(self,event):
        s= "Left Mouse Down at Point: (%.4f, %.4f)" % self.client._getXY(event)
        self.SetStatusText(s)
        event.Skip()            #allows plotCanvas OnMouseLeftDown to be called

    def OnMotion(self, event):
        #show closest point (when enbled)
        if self.client.GetEnablePointLabel() == True:
            #make up dict with info for the pointLabel
            #I've decided to mark the closest point on the closest curve
            dlst= self.client.GetClosestPoint( self.client._getXY(event), pointScaled= True)
            if dlst != []:    #returns [] if none
                curveNum, legend, pIndex, pointXY, scaledXY, distance = dlst
                #make up dictionary to pass to my user function (see DrawPointLabel) 
                mDataDict= {"curveNum":curveNum, "legend":legend, "pIndex":pIndex,\
                            "pointXY":pointXY, "scaledXY":scaledXY}
                #pass dict to update the pointLabel
                self.client.UpdatePointLabel(mDataDict)
        event.Skip()           #go to next handler
        
    def SetPointLabelFunc(self, func):
        """Sets the function with custom code for pointLabel drawing
            ******** more info needed ***************
        """
        self._pointLabelFunc= func
    ##end of new code        
        
def main():
    """Testing"""
   
    app = wx.PySimpleApp()
    f = MyFrame()
    f.Center()
    f.Show()
    app.MainLoop()


if __name__ == "__main__":
    main()
Sorry wegen dem PM, und vielen Dank für die schnelle Hilfe

mfg
Reinhard

Verfasst: Donnerstag 17. Juli 2008, 08:07
von Turri
Hallo Zusammen!

Das obige Beispiel funktioniert sehr gut.

Aber gibt es eine Möglichkeit die Beschriftung für jeden Punkt dauerhaft sichtbar zu machen ohne das OnMotion-Event?

Mein Problem ist, ich habe ein Diagramm mit vielen Werten und an einzelnen Punkten setze ich mir Marker (plot.PolyMarker) und diese Punkte möchte ich beschriften.

Kann mir da jemand weiterhelfen?
Bis jetzt hab ich es über SetPointLabelFunc versucht.
Die Pointlabels werden gezeichnet, allerdings nur ganz kurz angezeigt.
Die sind immer sofort wieder verschwunden.

Gibts eine Möglichkeit Punkte dauerhaft zu beschriften?

Ich dachte das passt ganz gut hier in den Thread.

MfG Turri

Verfasst: Donnerstag 17. Juli 2008, 10:08
von gerold
Turri hat geschrieben:Gibts eine Möglichkeit Punkte dauerhaft zu beschriften?
Hallo Turri!

Willkommen im Python-Forum!

Kurze Antwort: Ich glaube nicht. PyPlot ist ziemlich eingeschränkt. Alles was es kann, wird in der wxPython-Demo vorgezeigt. Mehr kann es nicht.

Wenn du mehr brauchst, dann musst du wahrscheinlich auf eine bessere Plot-Engine zurückgreifen.

- http://matplotlib.sourceforge.net/

mfg
Gerold
:-)

Verfasst: Donnerstag 17. Juli 2008, 11:00
von Turri
Hallo Gerold,

Danke für deine Antwort, dann werd ich mir matplotlib mal genauer anschauen. :-)

Danke!

MfG Turri