Python pandas - Achsenbeschriftung



  • Hallo zusammen,

    da ich momentan ein paar Daten Auswerten soll, mal eine Frage zu einer Skriptsprache. Da Python in der C++ Welt doch recht verbreitet ist, habe ich die Hoffnung, dass mir hier jemand weiter helfen kann.

    Ich möchte mit Python an Balkendiagramm erstellen. Es geht grob um die Anzahl von bestimmten Produkten.
    Daher ist auf der y-Achse die Anzahl aufgetragen und auf der x-Achse die Produkte. Das ganze ist Absteigend sortiert.

    Hier mal der Code:

    import pandas
    from collections import Counter, OrderedDict
    
    def plotBarChart(list, plotTitle):
       listCounter = Counter(list)
       ordered = OrderedDict(listCounter.most_common())
       df = pandas.DataFrame.from_dicts(ordered, orient = 'index')
       df.plot(kind = 'bar', legend = None, title = plotTitle)
    

    Mein Problem ist, dass die Produknamen an der X-Achste nicht komplett zu lesen sind, da sie abgeschnitten werden.
    Ich suche jetzt schon eine ganze Weile herum, um das irgendwie so hin zu kriegen, dass die Beschriftung komplett zu lesen ist und wollte mal Fragen, ob einer von euch damit schon Erfahrung gemacht hat und mir einen Tipp geben kann?

    Edit: Wenn ich die Anzahl der Säulen Beschränke, klappt es mit "barh". Im Prinzip suche ich nach einer Möglichkeit die Ausgabe in vertikaler Richtung zu vergrößern 😉


  • Mod

    Kann ich nicht nachvollziehen, selbst wenn ich absurd lange Namen mit tausenden von Zeichen benutze. Hast du da noch irgendwelche anderen Einschränkungen in der Programmumgebung laufen, die das eventuell verursachen?

    Getestet mit Pandas 0.22.0 und matplotlib 2.2.0 in Jupyter 5.0.0.

    import pandas
    from collections import Counter, OrderedDict
    
    def plotBarChart(list, plotTitle):
       listCounter = Counter(list)
       ordered = OrderedDict(listCounter.most_common())
       df = pandas.DataFrame.from_dict(ordered, orient = 'index')
       df.plot(kind = 'bar', legend = None, title = plotTitle)
    
    %matplotlib inline
    plotBarChart(['spam'*500, 'ham'*222, 'eggs']*20, 'Titel')
    


  • Hi,

    ich nutze: Python 3.6.4, Pandas 0.22.0 und anaconda 5.1.0

    Der Code:

    import matplotlib.pyplot as plt
    import pandas
    from collections import Counter, OrderedDict
    
    def plotBarChart(list, plotTitle):
       listCounter = Counter(list)
       ordered = OrderedDict(listCounter.most_common())
       df = pandas.DataFrame.from_dict(ordered, orient = 'index')
       df.plot(kind = 'bar', legend = None, title = plotTitle)
    
    plotBarChart(['myTestName1']*25 + ['myTestName2'], 'Titel')
    plt.show()
    

    führt zu folgendem Ergebnis: https://picload.org/view/dogadaca/test_pandas_plot.png.html
    Wie man sieht, ist das "m" unten abgeschnitten, bei maximaler Fenstergröße.

    Ich überlege grade, ob es daran liegen könnte, dass ich das in einer VM benutze und da aus irgendeinem Grund mit den Fenstergrößen was nicht passt.


  • Mod

    Interessant. Wenn ich das mal nicht in Jupyter sondern standalone ausführe, bekomme ich noch einmal ein anders Verhalten: Das Bild wird nicht beliebig groß wie in Jupyter, sondern ist immer 640*480. Die Beschriftung wird unten nicht abgeschnitten, sondern bei Bedarf wird die y-Achse kleiner skaliert, so dass immer die ganze Beschriftung passt, aber dafür der Plot selbst irgendwann halt ziemlich flach wird. Wenn die Schrift so lang wird, dass die y-Achse ganz verschwinden würde, bekomme ich einen Fehler, dass die untere Kante des Plots nicht über der oberen Kante liegen dürfe, wahrscheinlich weil der Plotter halt berechnet, an welche Position er die x-Achse legen muss, damit die Schrift noch passt und irgendwann liegt diese dann halt über der oberen Kante.

    Bei diesen ganzen Mach-Dir-Das-Leben-Einfach Frameworks ist halt verdammt viel Magie drin. Offenbar kommt es sehr darauf an, in welcher Umgebung genau man gerade unterwegs ist, wie man an unseren drei völlig unterschiedlichen Ergebnissen sieht. Es ist zwar schön einfach, damit schnell einen halbwegs ansprechenden Plot zu erzeugen, aber wehe wenn man mal Sonderwünsche oder Probleme hat. Dann können einem nicht einmal andere Leute helfen, weil jeder ein bisschen was anderes sieht.



  • Spannende Angelegenheit, trotzdem Danke für deine Mühen.


  • Mod

    Ein bisschen Anleitung zur Selbsthilfe: Erst einmal gilt zu überlegen, welches Verhalten gewünscht ist. Soll das Bild pixelmäßig größer werden, also wie das Verhalten bei mir im Jupyter? Soll der Plot in dem Bild kleiner werden, wie bei mir standalone? Soll etwas ganz anderes passieren (es ist zum Beispiel auch möglich, die Schrift diagonal zu platzieren)?

    Die ganz einfachen Parameter - wie die Größe - lassen sich direkt in der Plot-Funktion von Pandas konfigurieren. Da kann man dann vielleicht so halbautomatisch Anpassungen vornehmen und z.B. eine größere bildfläche vorgeben, wenn die Texte länger sind. Es ist auch möglich, das Plot-Objekt nach dem DatFrame.plot und vor dem plot.show noch zu manipulieren, um ein paar schwierigere Dinge anzupassen. Ohne es getestet zu haben, würde ich an dieser Stelle suchen, wenn ich beispielsweise die Schriftausrichtung geändert haben möchte. Eventuell auch zuerst ohne Beschriftung plotten und dann später dem Plot noch Schrift hinzufügen, bevor man ihn anzeigt.

    Wenn du die volle Freiheit willst, musst du umgekehrt vorgehen und direkt mit den matplotlib-Primitiven den DataFrame selber nach deinen Wünschen plotten. Damit sollte dann so ziemlich alles möglich sein, aber es ist schon viel Arbeit, überhaupt auf das Niveau der pandas-Plotfunktion zu kommen. Sprich: Ohne viel Arbeit wird dein Plot anfangs scheiße aussehen, aber mit genügend Arbeit kannst du die Pandasfunktion übertreffen.



  • Vielen Dank für die Hinweise. Das werde ich mir bei Gelegenheit noch genauer anschauen, aber für so "Randtätigkeiten" entsprechende Ressourcen freizuschaufeln ist halt nicht so einfach 😉

    Das show() dient hier nur der Demonstration bzw. hat mir als "Debugausgabe" geholfen. Ich setze prinzipiell die Größe des Plots automatisch und speicher verschiedene Grafen in entsprechende Dateien.
    Ursprünglich hatte ich mit der matplotlib angefangen, bin dann aber über die pandas Funktionalitäten gestolpert, mit der ich erstmal schneller zum Ziel gekommen bin.

    Wenn das irgendwann alles schöner und nach spezielleren Wünschen gestaltet sein soll, muss ich da insgesamt tiefer einsteigen.


  • Mod

    Nichtsdestotrotz enthält eine matplotlib-figure auch eine abstrakte Beschreibung des Inhalts. Es ist durchaus möglich, eine Figureauf high-level Niveau zu ändern. Irgendwann, wenn du sie speicherst, anzeigst oder ausdruckst, werden dann auch konkrete Pixel berechnet (die auch Teil des figure-Objekts sind, aber das ist ein Implemntierungsdetails) und dann landet halt die derzeitige Inhaltsbeschreibung in der Datei, auf dem Papier, oder auf dem Bildschirm. Aber es gibt stets einen Moment zwischen dem DataFrame.plot und dem Schritt, bei dem tatsächlich gerendert wird. Dazwischen kannst du die figure noch andern.


Anmelden zum Antworten