Nachdem es in Teil 1 erstmal etwas allgemeines Bla zu Python gab, wollen wir uns heute SciPy & Co. zuwenden. Bzw. muss ich jetzt genauer sein, denn eigentlich geht es um PyLab, das vereint die wissenschaftliche Bibliothek SciPy, dazugehörend NumPy zur Arbeit mit Arrays, matplotlib zum Grafiken erzeugen und eine Erweiterung zu IPython, um dynamisch mit einer Python-Konsole zu arbeiten.
PyLab ist noch im Entstehen, aber die Teilpakete sind alle weit entwickelt und (im Vergleich zu den meisten anderen Bibliotheken) gut dokumentiert. Es kann noch ein wenig zu Namensverwirrungen um die Module kommen, aber in neueren Installationen sollte sich durch

from pylab import *

alles notwendige importieren lassen, um mit allen Funktionen zu arbeiten.

Heute wenden wir uns einem der wichtigsten Themen beim Erstellen wissenschaftlicher Texte zu: den bunten Bildchen. Wenn man mal die Bildchen erzeugt hat, hat man meist schon den Großteil der Datenauswertung geschafft, gut, man muss dann noch dazuschreiben was man sieht und die Fehler wegdiskutieren und so 😉
Schauen wir uns vier einfache Beispiele an, denn mit matplotlib lassen sich unschlagbar schnell einfache Plots erzeugen. Als erstes erstellen wir ein Histogramm, dann eine Punkt- und einen Linienplot und schließlich noch einen Kontourplot.

**1. Histogramm**

Nehmen wir also an, wir haben einen Haufen Zahlenwerte und interessieren uns, wie diese verteilt sind. Dazu können wir ein Histogramm erzeugen, das zählt die Werte in eine gegebene Anzahl Kistchen ein (“bins”). Ok, wir bereiten erstmal eine Liste mit allen Zahlenwerten vor. Dazu kann man ein *numpy*-Array nehmen, muss man aber nicht, eine einfache Liste tut es. Sagen wir mal, wir haben eine Datei *daten.txt* in der pro Zeile ein Wert steht. Dann laden wir diese und speichern sie in eine Liste:

from pylab import *

datenList = [] # leere Liste
f = open("daten.txt")
for line in f:
    line = line.rstrip() 
    datenList.append(float(line))

*rstrip* entfernt leere Zeichen am Anfang und Ende sowie Zeilenumbrüche.
So, jetzt erzeugen wir ein Histogram aus der Liste mit 10 bins:

hist(datenList,10)
show()

Das wars? Ja, das wars. Es öffnet sich ein Betrachterfenster mit dem Histogramm, aus dem man es auch abspeichern kann. Mit *savefig(fname)* statt *show* kann man es auch unter dem Dateinamen *fname* abspeichern. Das Grafikformat wird dabei aus der Dateinamen-Endung erkannt. Und so könnte ein Histogramm aussehen:

i-4796b5a4537b1c8393b0fde44dc18742-hist-thumb-350x262.png

**2. Punktwolke**

Die häufigsten Daten sollten Funktionswerte sein, also (x,y)-Werte. Sagen wir also, wir haben eine Datei mit einem Haufen unabhängiger Ergebnisse, z.B. von einem Haufen Simulationsläufe mit jeweils leicht unterschiedlichen Bedingungen. Diese wollen wir einlesen und als Punkte darstellen. Dann könnte das z.B. so aussehen:

from pylab import *

xList = [] # leere Liste
yList = []

f = open("daten.txt")

for line in f:
    line = line.rstrip() 
    parts = line.split()
    xList.append(float(parts[0]))
    yList.append(float(parts[1]))

plot(xList,yList, 'ro')
axis([0,10,0,1])
show()

Unsere Datei listet in jeder Zeile einen x und y-Wert mit Leerzeichen getrennt. *split* teilt einen String auf, ohne Angabe in Klammer automatisch am Leerezeichen. Man könnte z.B. auch an einem Strich trennen mit *split(‘-‘)*. Man erhält eine Liste mit den Stringteilen ohne die Trennzeichen. Also hier ist *parts[0]* der x- und *parts[1]* der y-Wert. Die stecken wir in zwei Listen und die wiederum in *plot(…)*. Der dritte Parameter zu *plot* sorgt für rote Punkte. Eine Liste der möglichen Angaben hier findet sich in der Dokumentation zu plot. Schließlich sorgt *axis* dafür, von wo nach wo die x- und y-Achse gehen sollen, damit auch alle Punkte gut zu sehen sind. So könnte der Plot aussehen:

i-385f42a95781db2a05dce6e7fa0e8d2d-points-thumb-350x262.png

**3. Linienplot**

Ohne Formatangabe als dritter Parameter würde automatisch eine Linie gezeichnet. Wir wollen jetzt aus zwei Datensätzen einen Plot mit zwei Linien zeichnen. Auch das ist ganz einfach.

from pylab import *

def readXYDataFromFile(filename):
    xList = []
    yList = []

    f = open(filename)

    for line in f:
        line = line.rstrip() 
        parts = line.split()
        xList.append(float(parts[0]))
        yList.append(float(parts[1]))

    return (xList,yList)

(xListA, yListA) = readXYDataFromFile("linie1.txt")
(xListB, yListB) = readXYDataFromFile("linie2.txt")

plot(xListA, yListA, label="blau")
plot(xListB, yListB, 'm-.', linewidth=3., label="magenta")
legend()

show()

Das Einlesen habe ich jetzt in eine Funktion ausgelagert, um es nicht doppelt schreiben zu müssen.
Man sieht, wenn man einfach zweimal hintereinander *plot* aufruft, werden mit dem *show()* beide Plots in ein Bild gezeichnet. Mit *label* lässt sich ein Name festlegen, der später für *legend* verwendet wird. Der zweite plot soll sich unterscheiden, deswegen habe ich ihm nochmal ein Format mitgegeben, *’m-.’ für magenta Strichpunkt-Linie, und auch noch die Liniendicke hochgesetzt. So sieht es dann aus:

i-4195f3c02bc127e635048a92a87e8a8a-linien-thumb-350x262.png

**4. Kontourplot**

Und schließlich will ich noch – ganz kurz – den Kontourplot zeigen. Die Voraussetzung dazu ist, das man durch x- und y-Koordinaten die Punkte eines Gitters angibt und dann auf jedem Gitterpunkt einen Wert hat. Diese Werte stellt man farblich codiert da, und der Kontourplot ist eine interpolierte Darstellung die für die ganze Fläche durch Farbbereiche den Werteverlauf kennzeichnet.

from pylab import *

N = 20
x = linspace(.0, 1.0, N)
y = linspace(.0, 1.0, N)

X, Y = meshgrid(x, y)

Z = sin(X+0.2) - 2*cos(Y*1.2)

contourf(X, Y, Z)
colorbar()

show()

Auch hier wieder nur ein ganz einfaches Beispiel um das Prinzip zu zeigen, in der Dokumentation finden sich wieder umfangreichere Beispiele. Zunächst brauchen wir jetzt *numpy*-Funktionen. *linspace* erzeugt eine Liste von 20 Werten im Bereich zwischen 0 und 1. So haben wir die x- und y-Aufteilung unseres Gitters. Gut, dass es auch *meshgrid* gibt, das dann dafür die 400 Gitterpunkt koordiniert…
Als Werte hab ich einfach eine Funktion zusammengestöpselt. Python mit PyLab ist clever genug, um automatisch das richtige herauszuwerfen, wenn man die Listen X und Y in die Funktion steckt, nämlich ein 20×20-Feld. Und wieder ist das Plotten simpel! *contourf* erzeugt den gefüllten Kontourplot, will man nur Höhenlinien, verwendet man *contour*. Man übergibt die Gitterkoordinaten in *X, Y* und das Wertefeld in *Z*. Schließlich ruft man noch *colorbar* auf, um den Farbbalken mit dem Wertebereich anzeigen zu lassen. Fertig!

i-0907ba0df015f36cf94807d1d7a73bb1-contour-thumb-350x262.png

Viele weitere, schönere Beispiele finden sich übrigens z.B. hier. Die Möglichkeiten sind unerschöpflich, und wer noch mehr braucht als diese Arten (z.B. komplizierteres 3D), kann sich z.B. auch mal MayaVi anschauen.

Kommentare (10)

  1. #1 creeky belly
    04/10/2009

    Ich habe “ion()” und “ioff()” nützlich gefunden; es macht das Plotten schneller. Zum Beispiel:

    ioff()

    pylab.plot(X,Y1)
    …..
    pylab.plot(X,YN)

    ion()
    show()

    Es arbeitet am besten für groß ‘N’.

    “pylab.load()” ist auch nützlich. Es arbeitet die selben wie:

    f = open(“daten.txt”)
    for line in f:
    line = line.rstrip()
    datenList.append(float(line))

    aber für (N x M) Daten auch. (Es macht ein numpy.array).

    Entschuldigungen für mein schrecklich Deutsch. :-)

  2. #2 Bernd
    04/24/2009

    Python-Einsteigerbuch gekauf, Python, NumPy & SciPy installiert — es kann losgehen. Danke für die Einsichten.

  3. #3 jo
    05/27/2009

    hallo,
    ich hab eine Text-Datei mit mehreren verschiedenen werten. zB: temp,time, etot usw.
    ich hab Probleme die Datei in so huebschen Bildern wie oben darzustellen.

    gebt mir mal Tipps

    mfg

  4. #4 JörgR
    05/27/2009

    Hallo jo,

    wie ist denn das genaue Format der Textdatei; und welche Art Grafik soll es werden?

  5. #5 beka
    05/28/2009

    Was spricht gegen die Verwendung von gnuplot? Der Leistungsumfang (siehe under demos) und die Ausgabe nach TeX, EPS oder PDF sind doch genial.

    Für riesige Datenmengen eignet sich DynaWorks von Intespace.

  6. #6 jo
    06/04/2009

    hallo joerg,
    danke fuer deine antwort.
    die grafik sollte entweder wie 1.,2. oder 3. sein (siehe oben)
    datei is normale textdatei ,also txt. , die ich im terminal mit gedit oeffnen kann.

    mfg jonas

  7. #7 jonas
    06/29/2009

    ich moechte die text datei einlesen.in der textdatei sind zahlreiche messwerte.ich moechte nun das das programm die einzelnen variablen und die dazu gehoerigen messwerte ausgibt, welche der nutzer zuvor bestimmt hat.er soll 2 variablen auswaehlen zu beispiel temperatur und druck.

    dann sollen die messwerte umgewandelt werden in eine grafik. diagramm histogram oder aehnliches.

    koennt ihr mir ma helfen?
    mfg hier etwas von der textdatei:

    NMR restraints: Bond = 0.000 Angle = 0.000 Torsion = 0.000
    ===============================================================================

    NSTEP = 1000 TIME(PS) = 1.000 TEMP(K) = 47.08 PRESS = 0.0
    Etot = -20159.1618 EKtot = 8.6079 EPtot = -20167.7697
    BOND = 0.7916 ANGLE = 29.0493 DIHED = 1.2577
    1-4 NB = 3.5567 1-4 EEL = 1.6205 VDWAALS = -48.5778
    EELEC = -20155.4695 EHBOND = 0.0000 RESTRAINT = 0.0018
    EAMBER (non-restraint) = -20167.7715
    Ewald error estimate: 0.8708E+00
    ——————————————————————————

    NMR restraints: Bond = 0.002 Angle = 0.000 Torsion = 0.000
    ===============================================================================

    NSTEP = 2000 TIME(PS) = 2.000 TEMP(K) = 46.14 PRESS = 0. usw.

  8. #8 JörgR
    07/02/2009

    @jonas
    Sorry für die späte Antwort

    Ist das Format immer so? Also sind immer genau diese Variablen in diesem Format so angegeben? Dann kriegt man das leichter hin als wenn die Variablen irgendeinen Namen haben können.

  9. #9 newbie
    07/09/2009

    Netter Einstieg in die Materie, allerdings finde ich load aus Kommentar 1 sehr viel besser fürs aarbeiten mit beliebigen ascii daten.

    Bei mir war es eine 252×400 tab-delimited ascii Datei, die ich über einzelnes Zeilenlesen nur mühsam mit mehreren for Schleifen in einen array bekommen hätte.

    Die Lösung
    a=load(‘file’)
    imshow(a)
    zeigt dann schon den gewünschten plot…

  10. #10 Jan W.
    02/23/2012

    Ich habe ehrlich gesagt anfangs nicht verstanden, wie die Installation/Verwendung von pylab funktionieren soll. Verwirrt hat mich dieser erste Google-Treffer: http://www.scipy.org/PyLab Auf der Seite geht es um die Idee, scipy, numpy und matplotlib in eins zu verknüpfen.

    pylab ist jedoch gleichzeitig der Name eines Moduls von matplotlib. Wenn man einzeln von http://www.scipy.org scipy und numpy sowie matplotlib von http://matplotlib.sourceforge.net/ installiert, geht es. Nur, falls sich jemand die gleiche Frage stellt.

    Ansonsten vielen Dank für diese Einführung!