Python und matplotlib

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
3ff
User
Beiträge: 191
Registriert: Dienstag 22. Dezember 2009, 12:54
Wohnort: Odenwald Sued-Hessen

Hallo Gemeinde,
irgendwie ist mein letzter Beitrag verschwunden.
Zu matplotlib gibts 1 gute Quelle:
matplotlib.sourceforge.net/examples/
besser ist folgendes:
locate matplotlib
dann kam bei meinem Ubuntu 9.1
/usr/share/doc/python-matplotlib-doc/examples/mplot3d/bars3d_demo.py

die Datei versteht der Python-Interpreter die Bibs sind schon alle auf Ubuntu angepasst.
----------------------------------------
Super, denn ich muss mit Latex und 1 Beamer Vortraege halten und da kam es mir sehr recht
Der Suchpfad wird bei Suse oder Mandrake bestimmt anders lauten.
Goode!
Fritz 8) 8)
maria_dolores
User
Beiträge: 39
Registriert: Dienstag 10. August 2010, 12:38

@BlackJack: Kannst Du mir vielleicht per Code sagen wie und wo ich die Achsen weglassen soll.. hemhem.. :? Ich hab es zwar eben versucht, aber ich weiss nicht genau wo ich das dann machen muss.

Gruß Isa
MTroi
User
Beiträge: 2
Registriert: Mittwoch 11. August 2010, 11:48

Hallo!
Ich habe ein ähnliches Problem beim Zeichnen meines Graphen und hoffe auf eure Hilfe.

Erläuterung: Der Graph basiert aus Werten der "*-result.csv" (s- ganz unten) in der gemessene Werte für
Up- und Downstream eines DSL Modems drinstehen sowie Richtwerte die als Vorgabe für die verschiedene
Leitungslängen dienen.
Der Graph stellt nun die Richtwerte als gestrichelte und die gemessenen Werte als durchgezogene Linie dar,
wobei die linke y-Achse für die Upstream und die rechte y-Achse für den Downstream stehen und
über die x-Achse die Leitungslänge aufgetragen ist.

Das Problem:
Das zeichnen klappt auch, aber die Zuordnung von Y-Werten zur X-Achse ist völlig falsch.
Ich hoffe hier kann mir jemand eine Lösung finden oder zumindest das Problem genau benennen, ich selber
bin jetzt mit meinem Latein am Ende.

Code: Alles auswählen

#Import needed Modules
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.mlab import csv2rec
import matplotlib.font_manager
from pylab import *

filename = "test"

if __name__ == "__main__":
    
    print "Generating Graph"
    
    prop = matplotlib.font_manager.FontProperties(size=10) #Set Font Size
    
    data = csv2rec(filename + "-result.csv",delimiter=',') #Read csv File
    
    N = len(data['length_m']) #Get # of lengths
    Up_Exp = data['up_rate_expected_kbps'] #Read Data From Corresponding Columns
    Up_Meas = data['up_rate_measured_kbps']
    Down_Exp = data['ds_rate_expected_kbps']
    Down_Meas = data['ds_rate_measured_kbps']
    
    ind = np.arange(N)  # The X Locations
    
    fig = plt.figure() #Make Graph
    ax1 = fig.add_subplot(111)

    line1 = ax1.plot(ind, Up_Exp, color='b', ls='dashdot')
    line2 = ax1.plot(ind, Up_Meas, color='b')
    
    ax2 = ax1.twinx()
    line3 = ax2.plot(ind, Down_Exp, color='r', ls='dashdot')
    line4 = ax2.plot(ind, Down_Meas, color='r')
    
    for Up_Exp in ax1.get_yticklabels(): #Color for the US Values blue
	Up_Exp.set_color('b')
    
    for Down_Exp in ax2.get_yticklabels(): # Color for the DS Values red
	Down_Exp.set_color('r')
	    
    ax1.set_ylim(ymin=0) #Start with 0 
    ax2.set_ylim(ymin=0) #Start with 0
    #ax1.yaxis.grid(color='grey', linestyle='dashed')
    #ax2.yaxis.grid(color='grey', linestyle='dashed')
    ax1.xaxis.grid(color='gray', linestyle='dashed') #For better orientation
    ax1.set_ylabel('Upstream Rate (kbps)')
    ax2.set_ylabel('Downstream Rate (kbps)')
    ax1.set_xticklabels(data['length_m'])
    ax1.set_title('Up- and Downstream Values')
	
    ax2.legend( (line1[0], line2[0], line3[0], line4[0]), ('Up (mandatory)', 'Up (measured)', 'Down (mandatory)', 'Down (measured)'), prop=prop, loc=0 )

    result_graph = filename + '-graph.png'
    savefig(result_graph)
Das Resultat:
Bild

Mein test-result.csv:
Length (m),"UP Rate (Expected, kbps)","UP Rate (Measured, kbps)",Pass/Fail, UP Noise Margin (dB),"DS Rate (Expected, kbps)","DS Rate (Measured, kbps)",Pass/Fail,DS Noise Margin (dB)
150,10000,12468,PASS,5.6,44192,50380,PASS,5.6
300,9000,11464,PASS,5.7,40712,43388,PASS,5.7
750,7600,7896,PASS,6.1,27076,30240,PASS,6.1
1200,1328,1756,PASS,9.7,17328,23404,PASS,9.7
1800,748,0,FAIL,0.0,8380,0,FAIL,0.0
maria_dolores
User
Beiträge: 39
Registriert: Dienstag 10. August 2010, 12:38

@BlackJack: Ich weiss jetzt, was Du mit löschen der Axen, bei denen nichts geplottet wird gemeint hast.
Ich habe mein Problem soeben gelöst.
Ich musste aus meinem Code folgendes löschen:

Code: Alles auswählen

ax3 = ax1.twinx()
ax4 = ax1.twinx()
ax5 = ax1.twinx()
Dann stehen auf der rechten y-Achse nur noch die KM von 0 bis 700.

Wenn ich bei einen logscale einfügen möchte, der aber nicht beo 10, sondern bei 0.01 anfängt, wie mache ich denn sowas?

Hier mein jetziger Plot:

Bild

Bei der zweiten Einheit der x-Achse verschwindet ein Balken rein optisch, weil die Daten da so klein sind. Ich möchte meine rechte y-Skala so abändern, dass man diese 'verschwundenen' Balken wieder erkennen kann.

Ich hoffe, ihr versteht was ich meine.

Hat da jemand eine Hinweis oder eine Lösung für mich?

Gruß Isa
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

@Isa:
einen log-Plot kannst du von der Matplotlib Gallery abschreiben:
semilogy()
http://matplotlib.sourceforge.net/examp ... _demo.html
Wenn die Werte genug klein sind so werden auch 10^-2 (0.01) dargestellt, denke ich.

@MTroi:

es ist nicht sehr höflich einen bestehenden Thread zu übernehmen. Aber die Lösung ist relativ einfach:
ersetze

Code: Alles auswählen

ind = np.arange(N)  # The X Locations
durch

Code: Alles auswählen

ind = data['length_m']
und lösche

Code: Alles auswählen

ax1.set_xticklabels(data['length_m'])
MTroi
User
Beiträge: 2
Registriert: Mittwoch 11. August 2010, 11:48

Verzeihung dass ich den Thread übernommen habe, aber das Thema war ja ähnlich und schien so gut wie abgeschlossen. Allerdings sicherlich kein netter Einstand von mir in diesem Forum. :roll:

Jedenfalls vielen Dank für die Lösung, es funktioniert nun endlich wie es soll.

Ich werde in Zukunft mehr Rücksicht zeigen.
3ff
User
Beiträge: 191
Registriert: Dienstag 22. Dezember 2009, 12:54
Wohnort: Odenwald Sued-Hessen

@ DaMutz
Danke, nur gut, das es dies Forum gibt. Ich hab das Programm auch am laufen.
Ich hab mal die csv Datei untersucht.
bei mir gab es kein Feld length_m
das war:
length m
und das ist ganz was anderes.
Eigentlich ist das Dateiformat der csv-files einfach: alle Felder werden entweder durch:
,
tab
etc getrennt.
Ich benutze matplotlib im Zusammenhang mit latex fuer beamerpraesentationen.
die matplotlib hat die Funktion Speichern in png-Format und dies Format kann man mit convert zu eps holen und dann in Latex integrieren.
In Deiner Fundstelle gibts auch Beispiele fuer 3D Darstellungen. Auch die laufen in Latex.
Streng genommen ist es natuerlich 2 1/2 D aber wir wollen nicht paepstlicher sein als der Papst.
Die Programmiersprache Python hat sich da auch schon reingehaengt und es gibt inzwischen viele Latex-Funktionen, die man ueber Python ausloesen kann.
Ich will allerdings bei Latex bleiben, ich hab
-viele Templates
-viele Vorlagen
und vorallem super Dokus.
Da kann sich riverbankcomputing/Nokia aber 1 Scheibe von abschneiden.
Guude!
Fritz 8) 8)
maria_dolores
User
Beiträge: 39
Registriert: Dienstag 10. August 2010, 12:38

@DaMutz: Danke, sieht jetzt sehr gut aus.

Da ich gerade schon beim Löcher-in-den-Bauch-fragen bin, habe ich spontan auch noch eine.

Es gibt ja diese time.strftime-Funktion, die in meinem Fall HH:MM:SS ausgibt. Wenn ich nun mehr als 24 Stunden habe, wie sage ich, dass ich sowas wie T:H:M:S möchte?
Ich habe schon mal nachgeschaut, welche Argumente es gibt, aber nichts gefunden, was dabei hilft.

Beispiel:

Code: Alles auswählen

import time
t = (1232116.009546) 
print time.strftime('%H:%M:%S', time.gmtime(t))
#Zeit ist in Sekunden
Das Ergebnis ist 06:15:16. Allerdings entspricht es nicht nur 6 Stunden, sondern 342:25:44, was 14 Tagen, 15 Stunden, 25 Minuten und 44 Sekunden entspricht. Ich hoffe, ihr versteht was ich meine.

Habt ihr eine Idee?

Gruß Isa
BlackJack

@maria_dolores: Da wirst Du Dir selber eine Funktion basteln müssen. So schwer ist das ja aber nicht. Ein bisschen Modulurechnung. Die `divmod()`-Funktion könnte da nützlich sein.
BlackJack

@3ff: CSV ist doch etwas komplizierter als nur ein Trennzeichen zwischen den Feldern. Das Trennzeichen und auch Zeilenumbrüche dürfen auch innerhalb der Felder vorkommen. Also braucht man dafür einen Mechanismus um diese Zeichen zu schützen. Und das Escapezeichen dafür muss man auch wieder schützen, denn auch das darf ja innerhalb von Feldern vorkommen.

Bei Matplotlib zu LaTeX über PNG und EPS zu gehen ist nicht der beste Weg. PNG ist ein Pixelformat, also nicht verlustfrei skalierbar. Matplotlib kann selbst schon PostScript erzeugen. Und auch PDF. Letzteres kann man mit `pdflatex` direkt verwenden und man bekommt im Ergebnis Diagramme, die man verlustfrei skalieren kann, also auch in optimaler Qualität drucken kann. Egal welche Auflösung beim Drucken verwendet wird.

Und könntest Du mal mit diesem ständigen und hier völlig deplatzierten und unsinnigen Nokia-bashen aufhören!? Wir haben ja mittlerweile alle verstanden, dass Du nicht in der Lage bist mit der Dokumentation von PyQt4 umzugehen. :roll:
3ff
User
Beiträge: 191
Registriert: Dienstag 22. Dezember 2009, 12:54
Wohnort: Odenwald Sued-Hessen

@Black Jack
Was heisst hier Nokia verpruegeln? Die geben doch 1 Sche... darum.
Fuer uns kommt das 1mal nicht infrage, wir haben es auf Halt gesetzt!
Du scheinst ja 1 abenteuerlichen Begriff von Doku zu haben.
Soweit dazu.
Jetzt noch 1 schoenen Nahmittag!
Fritz :(
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

H2O für 1 Unsinn schrei>!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Hyperion hat geschrieben:H2O für 1 Unsinn schrei>!
Ich fuerchte da hilft nur noch Schnaps.
BlackJack

@3ff: Du hast Deine Meinung dazu schon mehrfach kundgetan. Und sie hat in *diesem* Diskussionsfaden einfach nichts zu suchen. Andere kommen mit der Dokumentation sehr gut zurecht. Ich habe schon deutlich schlechtere gesehen -- und ja, auch bei kommerziellen Produkten.
maria_dolores
User
Beiträge: 39
Registriert: Dienstag 10. August 2010, 12:38

@BlackJack: Ich habe jetzt versucht mir eine solche Funktion zu bauen, habe aber noch ein Problemchen damit.

Ich möchte, dass die Sekunden, die der Funktion übergeben werden nicht manuell eingegeben werden, sondern automatisch. BIsher sieht es so aus:

Code: Alles auswählen

def day_hms(data):
     sek = data
     d,s = divmod(sek, 86400)
     h,s = divmod(sek, 3600)
     m,s = divmod(sek, 60)
print "%0.2f: %0.2f: %0.2f: %0.2f" % (d, h, m, s)
Wenn ich nun die Sekunden automatisch übergebe, dann motzt er und sagt

Code: Alles auswählen

d,s = divmod(sek, 86400)
TypeError: unsupported operand type(s) for divmod(): 'str' and 'int'
Hat jemand eine Idee, was ich da falsch mache und wie man es richtig machen könnte?

Gruß Isa
BlackJack

@maria_dolores: Du übergibst da eine Zeichenkette und versuchst die durch eine Zahl zu teilen. Das macht nicht viel Sinn.
maria_dolores
User
Beiträge: 39
Registriert: Dienstag 10. August 2010, 12:38

@BlackJack: Das sehe ich ein. Das macht wirklich nicht viel Sinn.

Wenn ich bei meiner Funktion eine konkrete Zahl eingebe, dann klappt es auch. Ist ja auch logisch. Ich möchte aber die Sekunden automatisch übergeben. Da es mit divmod so nicht funktioniert und strftime() auch nicht geht, weil da jeweils nur bis 24 Stunden gezählt wird und dann wieder bei 0 Stunden beginnt, weiss ich nicht, wie ich weitermachen kann.

Hast Du da eine Idee?

Gruß Isa
Zuletzt geändert von maria_dolores am Freitag 13. August 2010, 11:53, insgesamt 1-mal geändert.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ich glaube dann willst du dir mal datetime anschaun.
BlackJack

@maria_dolores: Was für eine Zeichenkette übergibst Du denn da?
maria_dolores
User
Beiträge: 39
Registriert: Dienstag 10. August 2010, 12:38

@cofi: Danke. Habe mir eben dateimte angeschaut. Prinzipiell eine super Lösung.

Nur kann ich hier scheinbar keine Argumente automatisch übergeben. Ich habe es so versucht:

Code: Alles auswählen

import datetime
a = 1232116.009546
sek = datetime.datetime(a)
print sek
Er motzt dann und sagt

Code: Alles auswählen

TypeError: Required argument 'month' (pos 2) not found
Woraus ich schließe, dass ich die Daten dann alle manuell eingeben soll.

@BlackJack: Ich übergebe dabei eigentlich nur eine Zahl. Es sieht bei mir so aus:
Ich habe eine Datenbank und mache eine Abfrage. (Das Ganze mit SQLite und dem SQLiteManager). Ich bekomme dann durch meine Abfrage unter anderem eine Zahl in Sekunden. Diese möchte ich dann nutzen, um sie erstens per ReportLab in eine Tabelle zu schreiben und zweitens um einen Plot zu erzeugen.

Ich habe aber nicht nur eine Abfrage, sondern bisher so um die 60. Dementsprechend ist es recht sinnvoll, das das alles automatisch klappt.

Ich weiss nur nicht, ob ich bei dem DateTime was falsch gemacht habe.. Ich arbeite jetzut erst seit 3 Wochen mit Python und kenne mich da noch nicht so aus.

Gruß Isa
Antworten