Seite 1 von 1

Dynamischer Plot mit matplotlib

Verfasst: Dienstag 3. April 2007, 05:41
von kommando_pimperlepim
Hallo
ich bin durch mein Studium neu in Python, also entschuldigt, wenn mein erstes Post am falschen Ort oder trivial ist, ich nehme jede Hilfe dankbar entgegen.

In unserem Skript ist ein Beispielcode, mit zwei Problemen:
ich verstehe ihn nicht,
er funktioniert auch nicht.

Code: Alles auswählen

from pylab import *
from numpy import *

t = linspace(0.0, pi, 100) # Zeiten
x = cos(t) # x- und y-Koordinaten
y = sin(t) # eines Punktes zu den Zeiten t

ion()
figure(0) # neues Fenster 0
subplot(111, autoscale_on=False)
axis([-1.2, 1.2, -.2, 1.2]) # plot mit festen Grenzen

punkt = plot([x[0]], [y[0]], marker=’o’, mfc=’r’, ms=3)
# Plot anlegen (mit 1. Position)
for j in arange(len(t)):
  setp(punkt[0], data=(x[j], y[j])) # in Schleife
# die anderen Werte zeigen
ioff()
show()
also an der interessanten Stelle

Code: Alles auswählen

punkt = plot([x[0]], [y[0]], marker=’o’, mfc=’r’, ms=3)
# Plot anlegen (mit 1. Position)
for j in arange(len(t)):
  setp(punkt[0], data=(x[j], y[j])) # in Schleife
macht python nichts, wenn ich ipython probiere, gibt er nach jedem Schleifenbefehl [None] zurück. Es wird auch nichts gezeichnet. Kann mir jemand erklären, was diese Zeilen genau tun. Dachte setp ist nur dafür da, im nachhinein optische attribute zu ändern.

Verfasst: Dienstag 3. April 2007, 05:49
von rayo
Hi

Ich kenn matplotlib nicht, aber ich denke sowas könnte vielleicht helfen:

Code: Alles auswählen

#alle Werte der Plotfunktion übergeben
punkt = plot(x, y, marker=’o’, mfc=’r’, ms=3)
#ohne die For-Schleife nacher weiter
ioff()
show() 
Was bei dir ev. Falsch ist:

Code: Alles auswählen

#nur einen Punkt zeichnen
punkt = plot([x[0]], [y[0]], marker=’o’, mfc=’r’, ms=3)

for j in arange(len(t)):
  #punkt[0] wird der einzige Punkt sein, der gemalt wurde, dieser wird immer verändert
  #also hast du nach dieser Schleife einen Punkt gezeichnet der alle Werte mal angenommen hat
  setp(punkt[0], data=(x[j], y[j]))
Gruss

Verfasst: Dienstag 3. April 2007, 08:16
von CM
Hoi "kommando_pimperlepim" und willkommen im Forum,

ich habe ein paar Fragen und vielleicht auch jetzt schon einen Hinweis:
- Welches Betriebssystem nutzt Du und wie hast Du matplotlib installiert? (Ich frage, weil die Konfiguration ggf. unterschiedlich ist, jenachdem, was die Leute nutzen.)
- Welches graphische Backend nutzt Du? (Unter UNIX-Derivaten mußt Du u. U. im setup-skript explizit angeben, welches Backend (Tk, wx, gtk) Du nutzen willst. Meist reicht aber auch die "auto"-Konfigurationsoption. Das hängt davon ab, was bei Dir wie installiert wurde. Insbesondere unter OSX gibt es manchmal Probleme.)
- Nutzt Du außer numpy noch ein anderes array-Modul? (Wenn pylab auf numarray zugreift und Du aber numpy anschließend importierst, kann es Probleme geben. Aber danach sieht es zunächst einmal nicht aus.)

Pylab ist gemacht, um ohne OO interaktiv etwas zu plotten. (Für größere Programme empfiehlt sich der OO-Ansatz mit matplotlib.) Daher siehst Du bei mancher Funktion "None" als Rückgabewert, wenn Du Pylab unter ipython einsetzt. Wie hast Du denn ipython gestartet? Mit der --pylab - Option? In dem Fall sollte

Code: Alles auswählen

plot([1,2,3])
funtionieren. Tut es das? In der Out-Zeile sollte jetzt etwas stehen wie "[<matplotlib.lines.Line2D instance at 0x2aaab34572d8>]". Dann erübrigt sich der Import von pylab.

Und schließlich: Kommentiere mal das ioff() aus. Du willst doch interactiv arbeiten?

Gruß,
Christian

Verfasst: Dienstag 3. April 2007, 08:29
von Rebecca
Irgendwie hatte sich bei mir beim Copy und Paste ein Steuerzeichen bei marker="o" eingeschlichten, nachdem ich das beseitigt hatte, funktioniert es bei mir. Geht bei dir ueberhaupt ein Grafik-Fenster auf? Ist eventuell deine Installation von matplotlib nicht in Ordnung?

Das mit den None in der Schleife in ipython ist ok.

Verfasst: Dienstag 3. April 2007, 13:03
von kommando_pimperlepim
rayo hat geschrieben: Ich kenn matplotlib nicht, aber ich denke sowas könnte vielleicht helfen:

Code: Alles auswählen

#alle Werte der Plotfunktion übergeben
punkt = plot(x, y, marker=’o’, mfc=’r’, ms=3)
#ohne die For-Schleife nacher weiter
ioff()
show() 
Dann würde aber alles auf einmal gezeichnet, wenn ich das soweit verstanden habe. Es soll aber zu sehen sein, wie sich das Bild aufbaut. Das wird durch die Schleife getan. (und falls zu schnell mit entsprechender sleep-Prozedur gebremst)
CM hat geschrieben: - Welches Betriebssystem nutzt Du und wie hast Du matplotlib installiert?
Ich nutze Windows 2000, und habe matplotlib zusammen mit python und ipython in einem für die Python-Vorlesung gemachten Paket installiert.
Als Editor nutze ich ConTEXT und Compiliere von da aus direkt. Könnte das Probleme verursachen?
CM hat geschrieben: - Welches graphische Backend nutzt Du? (Unter UNIX-Derivaten mußt Du u. U. im setup-skript explizit angeben, welches Backend (Tk, wx, gtk) Du nutzen willst. Meist reicht aber auch die "auto"-Konfigurationsoption. Das hängt davon ab, was bei Dir wie installiert wurde. Insbesondere unter OSX gibt es manchmal Probleme.)
Sorry, was heißt grafisches Beckend?
CM hat geschrieben: - Nutzt Du außer numpy noch ein anderes array-Modul? (Wenn pylab auf numarray zugreift und Du aber numpy anschließend importierst, kann es Probleme geben. Aber danach sieht es zunächst einmal nicht aus.)
Ich nutze nur die module im Code. Laut Vorlesung, sind die im Kurs verwendeten doppelt belegten Definitionen im zweiten aktueller, sodass die Reihenfolge stimmt.
CM hat geschrieben: Wie hast Du denn ipython gestartet? Mit der --pylab - Option? In dem Fall sollte

Code: Alles auswählen

plot([1,2,3])
funtionieren. Tut es das? In der Out-Zeile sollte jetzt etwas stehen wie "[<matplotlib.lines.Line2D instance at 0x2aaab34572d8>]". Dann erübrigt sich der Import von pylab.
Ich habe ipython nicht mit --pylab gestartet, sondern mit dem konventionellen MS-Doppelklick, aber es funktioniert trotzdem, der plotbefehl wird ausgeführt und liefert genau sowas ([<matplotlib.lines.Line2D instance at 0x017D6BE8>]).
CM hat geschrieben: Und schließlich: Kommentiere mal das ioff() aus. Du willst doch interactiv arbeiten?
Das soll nur interaktiv sein, damit sich das Bild sichtbar aufbaut. Danach kann ich doch dann ioff() schreiben, oder? Schließlich passiert ja nichts mehr.
Rebecca hat geschrieben:Irgendwie hatte sich bei mir beim Copy und Paste ein Steuerzeichen bei marker="o" eingeschlichten, nachdem ich das beseitigt hatte, funktioniert es bei mir. Geht bei dir ueberhaupt ein Grafik-Fenster auf? Ist eventuell deine Installation von matplotlib nicht in Ordnung?
Was ist ein Steuerzeichen?
Soweit ich das beurteilen kann, funktioniert matplotlib ganz gut, ich hab schon damit rumgespielt. (Funktionen zeichnen, Achsen einteilen ...)

Was mich noch verwirrt, ist: In ipython gibt es keine Fehler, aber es wird nichts außer dem Punkt gezeichnet. Wenn ich den kompletten Code aber über meinen Editor importiere, geht nur das schwarze Fenster auf und wieder zu, kein Grafikfenster. Ich habe dann eine Zeile

Code: Alles auswählen

raw_input('<press RETURN to quit>')
eingefügt, um das automatische Schließen zu verhindern und es schließt trotzdem sofort, was auf einen Abbruch schließen lässt, der im ipython nicht auftritt.

Was mich noch vielmehr verwirrt (weiß nicht, ob es mit dem Problem zu tun hat), wenn ich den kompletten Code bis auf die letzte Zeile

Code: Alles auswählen

raw_input('<press RETURN to quit>')
wegkommentiere, dann schließt das Programm trotzdem sofort, wenn ich den wegkommentierten Code lösche, dann erhalte ich erst die richtige Meldung '<press RETURN to quit>'

Entschuldigt, dass ich mich hier vielleicht etwas quer ausdrücke, ich kenne Python wirklich erst seit gestern. Der Code ist auch nicht von mir, weshalb ich wie gesagt, die entscheidenden zwei Zeilen auch nicht komplett verstehe. Unter anderem verwirrt mich, dass immerwieder punkt[0] aufgerufen wird.

Verfasst: Dienstag 3. April 2007, 13:29
von kommando_pimperlepim
Danke Rebecca, es waren ´ statt '. Jetzt bewegt sich der Punkt schonmal.

Verfasst: Dienstag 3. April 2007, 14:07
von CM
Hallo,

ich vermute das alles wird darauf hinauslaufen, daß niemand hier "die Pythonvorlesung" kennt. Das ist halt eine Zusammenstellung von Software für einen bestimmten Kurs - wo man nur hoffen kann, daß der Leiter / die Leiterin gut getestet hat.
kommando_pimperlepim hat geschrieben: Dann würde aber alles auf einmal gezeichnet, wenn ich das soweit verstanden habe. Es soll aber zu sehen sein, wie sich das Bild aufbaut. Das wird durch die Schleife getan. (und falls zu schnell mit entsprechender sleep-Prozedur gebremst)
Interessant. Jetzt verstehe ich auch wozu ion() und ioff() gut sind (funktioniert bei mir übrigens reibungslos. Wirklich schönes Beispiel.
kommando_pimperlepim hat geschrieben:
CM hat geschrieben: - Welches Betriebssystem nutzt Du und wie hast Du matplotlib installiert?
Ich nutze Windows 2000, und habe matplotlib zusammen mit python und ipython in einem für die Python-Vorlesung gemachten Paket installiert.
Als Editor nutze ich ConTEXT und Compiliere von da aus direkt. Könnte das Probleme verursachen?
Nein. Compilieren wirst Du im engeren Sinne ohnehin nichts, sondern wohl eher bloß ausführen.
kommando_pimperlepim hat geschrieben: Sorry, was heißt grafisches Beckend?
Na ja, irgendwoher muß Dein Rechner doch wissen wie er das Fenster zaubern will. Und pylab will das auch wissen. Also mußt Du irgendwo Tkinter, wxPython oder etwas vergleichbares installiert haben. (richtig: Backend) Als ich gelesen habe: "Es funktioniert nicht." habe ich zu kurz gedacht und gemeint es könnte daran liegen, aber wenn interaktives Plotting funktionieren soll und es da irgendwo klemmt, hätte man hier einsteigen müssen.
kommando_pimperlepim hat geschrieben: Ich nutze nur die module im Code. Laut Vorlesung, sind die im Kurs verwendeten doppelt belegten Definitionen im zweiten aktueller, sodass die Reihenfolge stimmt.
Wenn Du meinst, daß Dein pylab und Dein numpy verschieden aktuell sind, dann ist das so nicht richtig: matplotlib muß für eine best. Version von numpy verwendet werden. Einmal kompiliert kann man das nicht mehr ändern (außer durch erneutes kompilieren oder Tricks, auf die ich jetzt nicht eingehe). Ansonsten ist die Reihenfolge des Imports irrelevant. Anzumerken ist vielleicht aber, daß ein *-Import nicht so clever ist. (siehe tausendundein Thread hierzu im Forum)
kommando_pimperlepim hat geschrieben: Ich habe ipython nicht mit --pylab gestartet, sondern mit dem konventionellen MS-Doppelklick, aber es funktioniert trotzdem, der plotbefehl wird ausgeführt und liefert genau sowas ([<matplotlib.lines.Line2D instance at 0x017D6BE8>]).
Ok, ohne --pylab ist wohl korrekt, weil unter Windows.
kommando_pimperlepim hat geschrieben:
CM hat geschrieben: Und schließlich: Kommentiere mal das ioff() aus. Du willst doch interactiv arbeiten?
Das soll nur interaktiv sein, damit sich das Bild sichtbar aufbaut. Danach kann ich doch dann ioff() schreiben, oder? Schließlich passiert ja nichts mehr.
Habe inzwischen kapiert. (s.o.)
kommando_pimperlepim hat geschrieben: Was mich noch verwirrt, ist: In ipython gibt es keine Fehler, aber es wird nichts außer dem Punkt gezeichnet.
Das ist doch korrekt? Der Punkt sollte außerdem wandern und einen Bogen beschreiben.
kommando_pimperlepim hat geschrieben: Wenn ich den kompletten Code aber über meinen Editor importiere, geht nur das schwarze Fenster auf und wieder zu, kein Grafikfenster. Ich habe dann eine Zeile

Code: Alles auswählen

raw_input('<press RETURN to quit>')
eingefügt, um das automatische Schließen zu verhindern und es schließt trotzdem sofort, was auf einen Abbruch schließen lässt, der im ipython nicht auftritt.
Das klingt nach einem Problem in Deiner Entwicklungsumgebung. Kennt jemand den Editor gut?
kommando_pimperlepim hat geschrieben: Entschuldigt, dass ich mich hier vielleicht etwas quer ausdrücke, ich kenne Python wirklich erst seit gestern.
Dafür klingt Du schon ziemlich souverän ;-).
kommando_pimperlepim hat geschrieben: Der Code ist auch nicht von mir, weshalb ich wie gesagt, die entscheidenden zwei Zeilen auch nicht komplett verstehe. Unter anderem verwirrt mich, dass immerwieder punkt[0] aufgerufen wird.
Das liegt daran, daß plot() eine Liste zurückgibt und was diese Liste enhält siehst Du weiter oben (z.B. [<matplotlib.lines.Line2D instance at 0x2aaab38ba4d0>]). Die Instanz in der Liste, das ist wiederrum wonach setp begehrt ;-). Auf der matplotlib-Seite gibt es viele Beispiele und Dokumentation.

Gruß,
Christian

Verfasst: Dienstag 3. April 2007, 14:08
von CM
kommando_pimperlepim hat geschrieben:Danke Rebecca, es waren ´ statt '. Jetzt bewegt sich der Punkt schonmal.
:D Manchmal ist es so einfach ...
Na denn: Frohes Schaffen!