Ich benutze Matplotlib, um ein Histogramm zu erstellen.
Gibt es eine Möglichkeit, die Größe der Fächer im Gegensatz zur Anzahl der Fächer manuell festzulegen?
Ich benutze Matplotlib, um ein Histogramm zu erstellen.
Gibt es eine Möglichkeit, die Größe der Fächer im Gegensatz zur Anzahl der Fächer manuell festzulegen?
Antworten:
Eigentlich ist es ganz einfach: Anstelle der Anzahl der Bins können Sie eine Liste mit den Bin-Grenzen angeben. Sie können auch ungleich verteilt sein:
plt.hist(data, bins=[0, 10, 20, 30, 40, 50, 100])
Wenn Sie sie nur gleichmäßig verteilen möchten, können Sie einfach range verwenden:
plt.hist(data, bins=range(min(data), max(data) + binwidth, binwidth))
Zur ursprünglichen Antwort hinzugefügt
Die obige Zeile gilt nur für data
Ganzzahlen. Wie Macrocosme hervorhebt, können Sie für Schwimmer Folgendes verwenden:
import numpy as np
plt.hist(data, bins=np.arange(min(data), max(data) + binwidth, binwidth))
(data.max() - data.min()) / number_of_bins_you_want
. Das + binwidth
könnte geändert werden, 1
um dies zu einem leicht verständlichen Beispiel zu machen.
lw = 5, color = "white"
oder ähnliches fügt weiße Lücken zwischen Balken ein
Für N Fächer werden die Fachkanten durch eine Liste von N + 1-Werten angegeben, wobei das erste N die unteren Fachkanten und das +1 die obere Kante des letzten Fachs angibt.
Code:
from numpy import np; from pylab import *
bin_size = 0.1; min_edge = 0; max_edge = 2.5
N = (max_edge-min_edge)/bin_size; Nplus1 = N + 1
bin_list = np.linspace(min_edge, max_edge, Nplus1)
Beachten Sie, dass linspace ein Array von min_edge bis max_edge erzeugt, das in N + 1-Werte oder N Bins unterteilt ist
Ich denke, der einfache Weg wäre, das Minimum und Maximum der Daten zu berechnen, die Sie haben, und dann zu berechnen L = max - min
. Dann dividieren Sie L
durch die gewünschte Behälterbreite (ich gehe davon aus, dass dies mit der Behältergröße gemeint ist) und verwenden die Obergrenze dieses Werts als Anzahl der Behälter.
Ich mag es, wenn Dinge automatisch passieren und Mülleimer auf "schöne" Werte fallen. Das Folgende scheint ganz gut zu funktionieren.
import numpy as np
import numpy.random as random
import matplotlib.pyplot as plt
def compute_histogram_bins(data, desired_bin_size):
min_val = np.min(data)
max_val = np.max(data)
min_boundary = -1.0 * (min_val % desired_bin_size - min_val)
max_boundary = max_val - max_val % desired_bin_size + desired_bin_size
n_bins = int((max_boundary - min_boundary) / desired_bin_size) + 1
bins = np.linspace(min_boundary, max_boundary, n_bins)
return bins
if __name__ == '__main__':
data = np.random.random_sample(100) * 123.34 - 67.23
bins = compute_histogram_bins(data, 10.0)
print(bins)
plt.hist(data, bins=bins)
plt.xlabel('Value')
plt.ylabel('Counts')
plt.title('Compute Bins Example')
plt.grid(True)
plt.show()
Das Ergebnis sind Behälter in schönen Intervallen der Behältergröße.
[-70. -60. -50. -40. -30. -20. -10. 0. 10. 20. 30. 40. 50. 60.]
desired_bin_size=0.05
, min_boundary=0.850
, max_boundary=2.05
die Berechnung n_bins
wird int(23.999999999999993)
die Ergebnisse in 23 anstelle von 24 und damit ein Fach zu wenig. Eine Rundung vor der Ganzzahlkonvertierung hat bei mir funktioniert:n_bins = int(round((max_boundary - min_boundary) / desired_bin_size, 0)) + 1
Ich benutze Quantile, um Behälter einheitlich zu machen und an die Probe anzupassen:
bins=df['Generosity'].quantile([0,.05,0.1,0.15,0.20,0.25,0.3,0.35,0.40,0.45,0.5,0.55,0.6,0.65,0.70,0.75,0.80,0.85,0.90,0.95,1]).to_list()
plt.hist(df['Generosity'], bins=bins, normed=True, alpha=0.5, histtype='stepfilled', color='steelblue', edgecolor='none')
np.arange(0, 1.01, 0.5)
oder ersetzen np.linspace(0, 1, 21)
. Es gibt keine Kanten, aber ich verstehe, dass die Felder die gleiche Fläche haben, aber unterschiedliche Breite in der X-Achse?
Ich hatte das gleiche Problem wie OP (glaube ich!), Aber ich konnte es nicht so zum Laufen bringen, wie Lastalda es angegeben hatte. Ich weiß nicht, ob ich die Frage richtig interpretiert habe, aber ich habe eine andere Lösung gefunden (es ist wahrscheinlich eine wirklich schlechte Art, dies zu tun).
So habe ich es gemacht:
plt.hist([1,11,21,31,41], bins=[0,10,20,30,40,50], weights=[10,1,40,33,6]);
Was das schafft:
Der erste Parameter "initialisiert" also im Grunde den Behälter - ich erstelle speziell eine Zahl, die zwischen dem Bereich liegt, den ich im Parameter "Behälter" festgelegt habe.
Um dies zu demonstrieren, betrachten Sie das Array im ersten Parameter ([1,11,21,31,41]) und das Array 'bins' im zweiten Parameter ([0,10,20,30,40,50]). ::
Dann benutze ich den Parameter 'weight', um die Größe jedes Behälters zu definieren. Dies ist das Array, das für den Gewichtungsparameter verwendet wird: [10,1,40,33,6].
Der Behälter 0 bis 10 erhält also den Wert 10, der Behälter 11 bis 20 den Wert 1, der Behälter 21 bis 30 den Wert 40 usw.
Für ein Histogramm mit ganzzahligen x-Werten habe ich letztendlich verwendet
plt.hist(data, np.arange(min(data)-0.5, max(data)+0.5))
plt.xticks(range(min(data), max(data)))
Der Versatz von 0,5 zentriert die Bins auf den Werten der x-Achse. Der plt.xticks
Aufruf fügt für jede Ganzzahl ein Häkchen hinzu.