2015-12-03 7 views
7

TL'DR, die vertikalen Balkendiagramme werden in einer konventionellen Weise gezeigt - Dinge richten sich von links nach rechts. Wenn es jedoch in ein horizontales Balkendiagramm konvertiert wird (von bar bis barh), steht alles auf dem Kopf. Das heißt, für ein gruppiertes Balkendiagramm ist nicht nur die Reihenfolge der gruppierten Balken falsch, sondern auch die Reihenfolge der einzelnen Gruppen.Matplotlib, horizontales Balkendiagramm (Barh) ist auf dem Kopf stehend

Für zB die grafische Darstellung von http://dwheelerau.com/2014/05/28/pandas-data-analysis-new-zealanders-and-their-sheep/

enter image description here

Wenn Sie genau hinsehen, werden Sie feststellen, dass die in der Bar und Legende in umgekehrter Reihenfolge sind - Rindfleisch zeigt oben in der Legende, sondern auf der Unterseite in der Graph.

Als einfachste Demo, änderte ich kind='bar',-kind='barh', aus dieser graphischen Darstellung https://plot.ly/pandas/bar-charts/#pandas-grouped-bar-chart und das Ergebnis sieht wie folgt aus: https://plot.ly/7/~xpt/

das heißt, die Bars in der horizontalen gruppierte Balkendiagramm bestellt den Kopf.

Wie es zu beheben?

EDIT: @Ajean, es ist eigentlich nicht nur die Reihenfolge der gruppierten bar falsch ist, die Reihenfolge der einzelnen Gruppen falsch als gut. Die Grafik von Simple customization of matplotlib/pandas bar chart (labels, ticks, etc.) zeigt es deutlich:

the order of the each group is wrong

Wir können sehen, dass der Auftrag zu unkonventionell ist, weil die Menschen die Grafik erwarten top-down, mit „AAA“ an der Spitze zu sein, nicht der Boden .

Wenn Sie nach "Excel upside-down" suchen, werden Sie feststellen, dass sich die Leute überall in Excel über dieses Problem beschweren. Das Microsoft Excel hat eine Lösung dafür, hat Matplotlib/Panda/Searborn/Ploty/etc eine Lösung dafür?

+0

Sie könnten die Balkengriffe manuell in 'plt.legend' übergeben und sie so bestellen, wie Sie wollen. – DilithiumMatrix

+0

Nein, das Problem ist nicht die Legende, werfen Sie einen Blick auf https://plot.ly/7/~xpt/, A, B, C, D ist in der richtigen Reihenfolge. Es ist die Bar in der falschen Reihenfolge. – xpt

+2

Hmmm .... Ich glaube nicht, dass dies ein * Fehler * an sich ist, so viel wie ein Konventionsproblem. Die Balken sind typischerweise in aufsteigender Reihenfolge aufgelistet (d. H. Das erste Element ist "0", das zweite Element ist "1" usw.). Und in dem hier angezeigten Fall, der "von unten nach oben" ("oben" bedeutet "höher") ist, macht es Sinn, dass die ersten Balken am unteren Ende jeder Gruppe liegen. Das Problem ist, glaube ich, dass die * Konvention * für eine Legende "top-down" statt "bottom-up" ist. Wenn Sie es wirklich umkehren möchten, ist es wahrscheinlich am einfachsten, die Legendenkonvention zu ändern. – Ajean

Antwort

7

Ich glaube, die gemeinsame falsche Reihenfolge von Gruppen und Untergruppen läuft auf ein einziges Merkmal hinaus: dass die y Achse nach oben steigt, wie in einer gewöhnlichen Handlung. Versuchen Sie, die y Achse Ihrer Achsen wie in diesem Pandas losen Beispiel Umkehrung:

import numpy as np 
import matplotlib.pyplot as plt 

x=range(5) 
y=np.random.randn(5) 

#plot1: bar 
plt.figure() 
plt.bar(x,y) 

#plot2: barh, wrong order 
plt.figure() 
plt.barh(x,y) 

#plot3: barh with correct order: top-down y axis 
plt.figure() 
plt.barh(x,y) 
plt.gca().invert_yaxis() 
+0

Nein, wird es kaum tun. Sie werden die Reihenfolge der Jahre umkehren: 1994-2012 in umgekehrter Reihenfolge. –

+0

@CTZhu aber das ist irgendwie der Punkt, nicht wahr? Wenn in einer "Bar" -Plot 1994-> 2012 von links nach rechts geht, dann könnte man für eine "Barh" die gleiche Reihenfolge von oben nach unten wünschen. OP's Edit Sprichwort "' es ist eigentlich nicht nur die Reihenfolge der gruppierten Bar ist falsch, die Reihenfolge der einzelnen Gruppen ist auch falsch '"vorgeschlagen, dass dies eine gültige Lösung ist. Wenn er kommt und mir sagt, dass es nicht ist, werde ich die Antwort löschen. –

+0

@AndrasDeak, Ja, Andras, genau das wollte ich. Könnten Sie bitte auch eine Pandas-Lösung einwerfen? [This] (https://gist.github.com/suntong/0e04741f28d999eafc04) ist soweit ich selbst gehen kann. Du fängst von dort an, wenn du willst. Vielen Dank. – xpt

0

Ich werde dies prüfen, um einen Fehler sein, das heißt, die y-Position der Stäbe nicht korrekt zugeordnet sind. Der Patch ist jedoch relativ einfach:

Dies ist nur eine richtige Reihenfolge der Bars, und das heißt ..., die richtige Reihenfolge. Alles, was nicht die richtige Reihenfolge ist, ist daher eine fehlerhafte Reihenfolge. : P

In [63]: 

print df 
     Total_beef_cattle Total_dairy_cattle Total_sheep Total_deer \ 
1994   0.000000   0.000000  0.000000 0.000000 
2002   -11.025827   34.444950 -20.002034 33.858009 
2003   -8.344764   32.882482 -20.041908 37.229441 
2004   -11.895128   34.207998 -20.609926 42.707754 
2005   -12.366101   32.506699 -19.379727 38.499840 

     Total_pigs Total_horses 
1994 0.000000  0.000000 
2002 -19.100637  11.811093 
2003 -10.766476  18.504488 
2004 -8.072078  13.376472 
2005 -19.230733 -100.000000 
In [64]: 

ax = df.plot(kind='barh', sort_columns=True) 

#Get the actual bars 
bars = [item for item in ax.get_children() if isinstance(item, matplotlib.patches.Rectangle)] 
bars = bars[:df.size] 

#Reset the y positions for each bar 
bars_y = [plt.getp(item, 'y') for item in bars] 
for B, Y in zip(bars, np.flipud(np.array(bars_y).reshape(df.shape[::-1])).ravel()): 
    B.set_y(Y) 

enter image description here

0

Allgemeine Lösung ist einfach:

handles, labels = axis.get_legend_handles_labels() 
# reverse to keep order consistent 
axis.legend(reversed(handles), reversed(labels), loc='upper left') 
4

ich die einfachste Lösung für dieses Problem glauben, dass die Pandas Datenrahmen vor dem Plotten rückgängig ist.Zum Beispiel:

df = df.iloc[::-1] 
df.plot.barh(stacked=True); 

Meiner Meinung nach ist das ein Fehler in der Pandas Barh Funktion. Zumindest sollten Benutzer in der Lage sein, ein Argument wie reverse_order = True usw. zu übergeben.

+1

Dies sollte die akzeptierte Antwort sein. – dangom

Verwandte Themen