pyFmGraph (Artistic Last.fm Statistic)
http://pyfmgraph.sourceforge.net/graph2.png (Große Version)
Was ihr hier seht ist ein Graph erstellt aus den Daten die Last.fm so über die Zeit sammelt. Über www.audioscrobbler.net kann man darauf per xml zugreifen. Die Idee da so dar zu stellen ist zwar nicht von mir sondern von www.megamu.com aber nachdem der Typ absolut nicht auf meine Emails geantwortet hat, bin ich nicht drum rum gekommen selbst bei Null anzufangen.
Bis auf die Beschriftung ist das ganze in Python und der Python Imaging Library (PIL) gecodet. Das Programm hab ich freundlicherweise auf Sourceforge gestellt.
Gemacht hab ich den ganzen Aufwand für ein, ziemlich orginelles, Geburtstagsgeschenk. Das ganze hab ich auf zwei Meter Länge geplottet (geht in der Uni recht billig)
Zur Darstellung: Es wird dargestellt wann welcher Künstler wie häufig gehört wurde. Dickere Flächen bedeuten häufiger. Ein Artist hat eine Farbe. Blauere Farben bedeutet dass der Artist zeitlich früher zum ersten mal gehört wurde, rot heißt später.
Nachbearbeitet hab ich das ganze dann noch mit GIMP auf nem 4gb Ram PC, was bei einer Auflösung von 20000x5000 echt das mindeste ist.
EDIT by mawe: Link gefixt
- http://bash.org/?400459
Was man vom Code allerdings nicht sagen kann: Der ist ja grausam (sorry )
Ich werde mal versuchen, da durchzusteigen und ihn zu verbessern. Das Parsen des XML Codes kann man durch die Verwendung von ElementTree schon mal wesentlich übersichtlicher gestalten.
Um die Idee mit dem Webinterface tatsächlich umzusetzen, müsste man das Ganze vor allem erstmal so gestalten, dass man es als Modul verwenden kann. Auch das versuche ich mal umzusetzen.
Da ich allerdings noch ernste Verständnisschwierigkeiten habe, dauert es wohl bis nächstes Wochenende, ehe da greifbare Resultate vorliegen
Ich werde mal versuchen, da durchzusteigen und ihn zu verbessern. Das Parsen des XML Codes kann man durch die Verwendung von ElementTree schon mal wesentlich übersichtlicher gestalten.
Um die Idee mit dem Webinterface tatsächlich umzusetzen, müsste man das Ganze vor allem erstmal so gestalten, dass man es als Modul verwenden kann. Auch das versuche ich mal umzusetzen.
Da ich allerdings noch ernste Verständnisschwierigkeiten habe, dauert es wohl bis nächstes Wochenende, ehe da greifbare Resultate vorliegen
Wenn Du schon dabei bist, kannst Du das Backend auch herausziehen und austauschbar machen. Als SVG, PDF oder PS macht sich so eine Grafik sicher auch ganz gut.
Tja, dafür müsste ich erstmal den Code zum Zeichnen verstehen Ich habe noch nie Grafikprogrammierung gemacht. Zudem bräuchte man erstmal verschiedene Bibliotheken... vorerst wird es also höchstens ein PIL Backend geben...BlackJack hat geschrieben:Wenn Du schon dabei bist, kannst Du das Backend auch herausziehen und austauschbar machen. Als SVG, PDF oder PS macht sich so eine Grafik sicher auch ganz gut.
Ich habe noch ganz gut zu tun, den Code überhaupt erstmal in eine anständige, wartbare und verständliche Form zu bringen Erschwert wird die Sache durch die Tatsache, dass ich zur Zeit nur am Wochenende an den PC kann.
Wow, das sieht echt cool aus. War bestimmt sau schwer.
Da steht September! (Jag mir doch keinen so Schreck ein!)Y0Gi hat geschrieben:Respekt, das sieht sehr ansprechend aus. Einzig der "Septemer" würde mir jeden Tag ein bisschen weh tun, wenn ich das als Riesenposter an der Wand hätte
@lunar: Für Fragen stehe ich jederzeit zur Verfügung. Vielleicht schaff ich demnächst sogar das SVN Repository von SF.net zum laufen zu kriegen. Ich würde mich freuen wenn man zusammenarbeiten könnte. Ne automatische Schriftpositionierung wäre z.B. auch schön.
Svg ist leider nicht möglich da das Rasterizing ein Teil des Algorithmus ist.
- http://bash.org/?400459
Wieso sollte SVG (, PDF, PS) nicht möglich sein? Da musst Du halt die Bezierkurven nicht selber berechnen sondern nur die Stützpunkte in Pfade stecken.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Hmm, wenn du meinst... ich habe mir mal den Code angesehen.lunar hat geschrieben:Ich habe noch ganz gut zu tun, den Code überhaupt erstmal in eine anständige, wartbare und verständliche Form zu bringen
Meine Libeblingszeile ist glaube ich die folgende:
Code: Alles auswählen
if (artist[i] != 0) or (i == 0) or (i == len_week - 1) or (artist[i-1]) == 0 or (artist[i+1]) == 0:
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
wobei zu erwähnen ist, dass die Reihenfolge der Bedingungen entscheidend ist
Das Problem ist, dass ich die Bezierkurven nicht einfach übereinander stapeln kann, da die Stützpunkte nicht übereinander liegen. Momentan funktioniert es so, dass ich sie einfach pixelweise addiere. SVG wäre mir auch lieber.BlackJack hat geschrieben:Wieso sollte SVG (, PDF, PS) nicht möglich sein? Da musst Du halt die Bezierkurven nicht selber berechnen sondern nur die Stützpunkte in Pfade stecken.
- http://bash.org/?400459
Ne, weil die eben nicht übereinander liegen. Was ich machen müsste wäre es Bezierkurven in mehrere kleine Bezierkurven zu unterteilen. Und da hab ich mathematische Probleme. Ne Alternative wäre die Bezierkurven in Polygonzüge mit regelmäßigen x-Abständen zu unterteilen. Ich hab das mal in Maple Versucht und das Ergebniss war ziemlich wüst. Hier mal ne Zeichnung zum Problem:
http://homepages.uni-regensburg.de/~hua16585/bezier.svg
http://homepages.uni-regensburg.de/~hua16585/bezier.svg
- http://bash.org/?400459
Mein erster Versuch. Das git repo ist hier zu finden.
Die Ausgabe meines Codes sagt mir, dass da noch etwas nicht stimmt. Was, kann ich nicht sagen, der Code zum Zeichnen ist größtenteils 1:1 kopiert und notdürftig in das OOP Korsett gezwängt, da ich ihn immer noch nicht wirklich verstehe. Irgendwo habe ich da wohl was bei der Anpassung übersehen. Morgen werde ich vielleicht nochmal ein bisschen damit spielen, für Tipps wäre ich aber echt dankbar. Ansonsten gibts die fertige Version höchstwahrscheinlich erst nächstes Wochende (wenn überhaupt).
Eine Frage an den OP hätte ich allerdings schon mal: Du programmierst nicht lange in Python, oder? Im Code fallen viele Dinge auf, die gelinde gesagt ziemlich mies sind. Die dauernde Verwendung von range zur aufsteigenden Iteration über Zahlen wäre ja noch zu verschmerzen, aber sowas
ist ja grausam Das tut ja fast schon körperlich weg...
Die Ausgabe meines Codes sagt mir, dass da noch etwas nicht stimmt. Was, kann ich nicht sagen, der Code zum Zeichnen ist größtenteils 1:1 kopiert und notdürftig in das OOP Korsett gezwängt, da ich ihn immer noch nicht wirklich verstehe. Irgendwo habe ich da wohl was bei der Anpassung übersehen. Morgen werde ich vielleicht nochmal ein bisschen damit spielen, für Tipps wäre ich aber echt dankbar. Ansonsten gibts die fertige Version höchstwahrscheinlich erst nächstes Wochende (wenn überhaupt).
Eine Frage an den OP hätte ich allerdings schon mal: Du programmierst nicht lange in Python, oder? Im Code fallen viele Dinge auf, die gelinde gesagt ziemlich mies sind. Die dauernde Verwendung von range zur aufsteigenden Iteration über Zahlen wäre ja noch zu verschmerzen, aber sowas
Code: Alles auswählen
for nvec in range(len(curve))[1:-1]:
...
Sieht ja echt ganz schick aus mit OOP. Ich hab schon vor einiger Zeit mit Python angefangen, nur hab ich bisher hauptsächlich mit der Python Referenz beschäftigt und mir fehlt halt das know-How z.B. mit der Iterierung.
Zum Zeichencode, das funktioniert so:
(ich hab mal ein Bild gemalt: http://homepages.uni-regensburg.de/~hua16585/graph.svg
)
Als erstes holt er die Daten von Audioscrobbler und konvertiert sie in Vektoren. Diese sind in relativ regelmäßigen Abständen sofern Daten vorhanden waren. Damit Man eine annähernde Kurve bekommt werden jetzt an stellen wo keine Daten vorhanden sind Vektoren mit y-Wert 0 eingefügt (rot). Aber so, dass nicht mehr als zwei Null-Vektoren aufeinander folgen. Der nächste Schritt ist dann Voraussetzung zum zeichnen der Bezier-Kurven. Es werden Linear-Interpolierte Stützvektoren eingezeichnet (blau) an diesen liegen die Bezierkurven später dann tangential an. Jetzt werden Bezierkurven verwendet um Vektoren die die Bezierkurve annähern zu berechnen. Die Auflösung hierfür ist variabel, je grober, desto eckiger werden die Kurven später. Eine gute Erklärung von Bezierkurven findest du hier: http://www.gamedev.net/reference/articl ... le1808.asp
Jetzt besteht jede Kurve aus vielen Vektoren die eine einigermaßen rund sind. Also muss man das ganze nur noch übereinander stapeln.
Dazu werden zwischen den zwei nächstliegenden Vektoren die Pixelpositionen linear interpoliert. (Also Mittels Steigungsdreieck und zentrischer Streckung) Die Y-Werte werden dann einfach addiert.
Jetzt verstehst du sicher auch, warum es schwierig ist das ganze als svg zu exportieren. Die Bezier-Funktion muss nämlich zum übereinander stapeln explizit ausgeführt werden.
Was ich mir vorstellen könnte wäre höchstens, dass es eine Methode gibt eine Bezier kurve in mehrere zu zerlegen, so dass alle die gleiche X-Länge haben. Dann könnte man vielleicht einfach die Stützpunkte addieren.
Hoffe mal die Erklärung war verständlicher als der Code
Zum Zeichencode, das funktioniert so:
(ich hab mal ein Bild gemalt: http://homepages.uni-regensburg.de/~hua16585/graph.svg
)
Als erstes holt er die Daten von Audioscrobbler und konvertiert sie in Vektoren. Diese sind in relativ regelmäßigen Abständen sofern Daten vorhanden waren. Damit Man eine annähernde Kurve bekommt werden jetzt an stellen wo keine Daten vorhanden sind Vektoren mit y-Wert 0 eingefügt (rot). Aber so, dass nicht mehr als zwei Null-Vektoren aufeinander folgen. Der nächste Schritt ist dann Voraussetzung zum zeichnen der Bezier-Kurven. Es werden Linear-Interpolierte Stützvektoren eingezeichnet (blau) an diesen liegen die Bezierkurven später dann tangential an. Jetzt werden Bezierkurven verwendet um Vektoren die die Bezierkurve annähern zu berechnen. Die Auflösung hierfür ist variabel, je grober, desto eckiger werden die Kurven später. Eine gute Erklärung von Bezierkurven findest du hier: http://www.gamedev.net/reference/articl ... le1808.asp
Jetzt besteht jede Kurve aus vielen Vektoren die eine einigermaßen rund sind. Also muss man das ganze nur noch übereinander stapeln.
Dazu werden zwischen den zwei nächstliegenden Vektoren die Pixelpositionen linear interpoliert. (Also Mittels Steigungsdreieck und zentrischer Streckung) Die Y-Werte werden dann einfach addiert.
Jetzt verstehst du sicher auch, warum es schwierig ist das ganze als svg zu exportieren. Die Bezier-Funktion muss nämlich zum übereinander stapeln explizit ausgeführt werden.
Was ich mir vorstellen könnte wäre höchstens, dass es eine Methode gibt eine Bezier kurve in mehrere zu zerlegen, so dass alle die gleiche X-Länge haben. Dann könnte man vielleicht einfach die Stützpunkte addieren.
Hoffe mal die Erklärung war verständlicher als der Code
- http://bash.org/?400459
Tja, die Erklärung sagt mir nur bedingt was, dafür reichen meine mathematischen Kenntnisse momentan nicht aus (die Oberstufe ist ne Weile her, das Studium beginnt erst nächstes Jahr, da vergisst man einiges ).
Allerdings habe ich den Bug gefunden, jetzt zeichnet meine Version ihre Graphen ebenfalls korrekt. Die neue Version liegt im Repo, für git-Verweigerer gibts auch noch das Paste. Nächstes Wochenende kann ich mal versuchen, den Text direkt in das Bild zu integrieren. Mittels image.paste sollte das kein allzu großes Problem sein, nur die Platzierung der Text müsste noch optimiert werden. Dabei hoffe ich mal auf deine Hilfe
Das Kommandozeilen-Interface ist auch noch verbesserungsbedürftig, es fehlen Optionen, um z.B. die verwendete Schriftart anzugeben, oder die Verbosity des Loggings.
Allerdings habe ich den Bug gefunden, jetzt zeichnet meine Version ihre Graphen ebenfalls korrekt. Die neue Version liegt im Repo, für git-Verweigerer gibts auch noch das Paste. Nächstes Wochenende kann ich mal versuchen, den Text direkt in das Bild zu integrieren. Mittels image.paste sollte das kein allzu großes Problem sein, nur die Platzierung der Text müsste noch optimiert werden. Dabei hoffe ich mal auf deine Hilfe
Das Kommandozeilen-Interface ist auch noch verbesserungsbedürftig, es fehlen Optionen, um z.B. die verwendete Schriftart anzugeben, oder die Verbosity des Loggings.