Matplotlib Histogramm mit Auffangbehälter für hohe Werte
Ich habe ein array mit Werten, und ich möchte erstellen Sie ein Histogramm davon. Ich bin vor allem daran interessiert, die low-end zahlen, und sammeln wollen, jede Zahl über 300 in einer bin. Diese Ablage sollten die gleiche Breite wie alle anderen (genauso breit) - Ablagen. Wie kann ich dies tun?
Hinweis: diese Frage bezieht sich auf diese Frage: Definition der bin-Breite/x-Achse skalieren in Matplotlib Histogramm
Dies ist, was ich bisher ausprobiert:
import matplotlib.pyplot as plt
import numpy as np
def plot_histogram_01():
np.random.seed(1)
values_A = np.random.choice(np.arange(600), size=200, replace=True).tolist()
values_B = np.random.choice(np.arange(600), size=200, replace=True).tolist()
bins = [0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300, 600]
fig, ax = plt.subplots(figsize=(9, 5))
_, bins, patches = plt.hist([values_A, values_B], normed=1, # normed is deprecated and will be replaced by density
bins=bins,
color=['#3782CC', '#AFD5FA'],
label=['A', 'B'])
xlabels = np.array(bins[1:], dtype='|S4')
xlabels[-1] = '300+'
N_labels = len(xlabels)
plt.xlim([0, 600])
plt.xticks(25 * np.arange(N_labels) + 12.5)
ax.set_xticklabels(xlabels)
plt.yticks([])
plt.title('')
plt.setp(patches, linewidth=0)
plt.legend()
fig.tight_layout()
plt.savefig('my_plot_01.png')
plt.close()
Dies ist das Ergebnis, das sieht nicht schön aus:
Habe ich dann geändert, die Zeile mit xlim in:
plt.xlim([0, 325])
Mit folgendem Ergebnis:
Es sieht mehr oder weniger wie ich es will, aber der Letzte bin, ist jetzt nicht sichtbar. Welchen trick übersehe ich, zu visualisieren, diese Letzte bin, mit einer Breite von 25?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Numpy hat eine nützliche Funktion für den Umgang mit dieser:
np.clip
. Trotz, was der name klingen mag, ist es nicht entfernen Werte, die es nur limitiert auf den Bereich, den Sie angeben. Im Grunde führt Artem "dirty hack" inline. Sie können die Werte wie Sie sind, aber in derhist
nennen, nur wickeln Sie das array in einenp.clip
nennen, wie soDies ist angenehmer für eine Reihe von Gründen:
Es ist Weg schneller — zumindest für eine große Anzahl von Elementen. Numpy hat seine Arbeit auf C-Ebene. Betriebssystem auf python-Listen (wie im Artem ' s list comprehension) hat eine Menge Aufwand für jedes element. Grundsätzlich, wenn Sie jemals die Möglichkeit haben, den numpy, sollten Sie.
Du es richtig machst, wo es gebraucht wird, das reduziert die chance, Fehler in Ihrem code.
Brauchen Sie nicht zu halten eine zweite Kopie des Arrays hängen, das reduziert den Speicherverbrauch (außer in dieser einen Zeile) und weiter reduziert die Chancen, Fehler zu machen.
Mit
bins[0], bins[-1]
statt hart-Codierung der Werte reduziert die Chancen, Fehler zu machen, wieder, weil Sie ändern können die Behälter genau dort, wobins
definiert wurde; Sie brauchen nicht daran zu erinnern, um die änderung in der Aufrufclip
oder sonst irgendwo.Also um es alle zusammen, wie im OP:
xlabels = bins.astype(str)
,xlabels[-1] += '+'
xlabels = [str(b) for b in bins[1:]]
. Beide Versionen sind vernünftig, aber ich bleibe bei dem original, nur weil es mehr im Einklang mit dem OP. Aber es ist definitiv eine echte Verbesserung zu ändern, die zweite Zeile zuxlabels[-1] += '+'
.Sorry, ich bin nicht vertraut mit matplotlib. Also ich habe ein dirty hack für Sie. Ich habe einfach alle Werte, die größer als 300 in einer bin, und der verändert die bin-Größe.
Die Wurzel des Problems ist, dass matplotlib versucht alle Behälter auf dem Grundstück. In R würde ich meine konvertieren Papierkorb, um eine Faktor-variable ist, so sind Sie nicht so behandelt, als reelle zahlen.