Frage

Ich weiß, wie ein Histogramm erstellen (nur verwenden „mit Boxen“) in gnuplot, wenn meine DAT-Datei bereits Daten richtig binned hat. Gibt es eine Möglichkeit, eine Liste von Zahlen zu nehmen und die Benutzergrößen ein Histogramm basierend auf Bereiche und sind zu bieten haben gnuplot bietet?

War es hilfreich?

Lösung

ja, und seine schnelle und einfache aber sehr versteckt:

binwidth=5
bin(x,width)=width*floor(x/width)

plot 'datafile' using (bin($1,binwidth)):(1.0) smooth freq with boxes

überprüfen help smooth freq, um zu sehen, warum die oben genannten bildet ein Histogramm

mit Bereichen beschäftigen nur den xrange Variable gesetzt.

Andere Tipps

Ich habe ein paar Korrekturen / Ergänzungen Born2Smile die sehr nützliche Antwort:

  1. Leere Behälter verursacht das Feld für das benachbarte Fach in seinen Raum zu falsch zu verlängern; vermeiden diese mit set boxwidth binwidth
  2. In Born2Smile Version werden Bins als auf ihre untere Grenze zentriert gemacht. Streng sollten sie von dem unteren gebunden an der oberen Grenze verlängern. Dies kann durch Änderung der bin Funktion korrigiert werden: bin(x,width)=width*floor(x/width) + width/2.0

Seien Sie sehr vorsichtig: alle Antworten auf dieser Seite nimmt implizit die Entscheidung, wo der Binning beginnt - der linke Rand der am weitesten links ist, wenn Sie so will - aus der Hand des Benutzers. Wenn der Benutzer eine dieser Funktionen kombiniert für Binning Daten mit seiner / ihrer eigenen Entscheidung darüber, wo beginnt Binning (wie auf dem Blog gemacht wird, die oben gebunden ist) sind die Funktionen vor allem falsch. Mit einem beliebigen Ausgangspunkt für Binning ‚Min‘, die korrekte Funktion ist:

bin(x) = width*(floor((x-Min)/width)+0.5) + Min

Sie können sehen, warum dies richtig ist sequentiell (es hilft, ein paar Behälter zu ziehen und einen Punkt irgendwo in einem von ihnen). Subtrahieren Min aus dem Datenpunkt, um zu sehen, wie weit in den Binning-Bereich ist. dividieren dann durch binwidth so dass Sie effektiv in Einheiten von ‚Bins‘ arbeiten. Dann ‚Boden‘ geht das Ergebnis auf den linken Rand dieses Behälters, 0,5 hinzufügen, bis in der Mitte des Behälters zu gehen, multipliziert mit der Breite, so dass Sie nicht mehr arbeiten in Einheiten von Behältern, sondern in einer absoluten Skala wieder, dann schließlich auf dem Min hinzufügen zurück versetzten Sie zu Beginn abgezogen.

Betrachten Sie diese Funktion in Aktion:

Min = 0.25 # where binning starts
Max = 2.25 # where binning ends
n = 2 # the number of bins
width = (Max-Min)/n # binwidth; evaluates to 1.0
bin(x) = width*(floor((x-Min)/width)+0.5) + Min

z. der Wert 1.1 wirklich fällt im linken ist:

  • Diese Funktion ordnet sie richtig in der Mitte des linken ist (0,75);
  • Born2Smile Antwort, ist (x) = Breite * floor (x / Breite), falsch ordnet sie 1;
  • MAS90 Antwort, ist (x) = Breite * floor (x / Breite) + binwidth / 2.0, falsch ordnet sie 1.5.

Antwort Born2Smile das ist nur richtig, wenn die Klassengrenzen treten bei (n + 0,5) * binwidth (wobei n läuft über ganze Zahlen). MAS90 Antwort ist nur dann richtig, wenn die Klassengrenzen bei auftreten n * binwidth.

Haben Sie eine grafische Darstellung wie diese dargestellt werden soll? eingeben Bild Beschreibung hier Ja? Dann können Sie einen Blick auf meinem Blog-Artikel haben: http: //gnuplot-surprising.blogspot.com/2011/09/statistic-analysis-and-histogram.html

Key Linien aus dem Code:

n=100 #number of intervals
max=3. #max value
min=-3. #min value
width=(max-min)/n #interval width
#function used to map a value to the intervals
hist(x,width)=width*floor(x/width)+width/2.0
set boxwidth width*0.9
set style fill solid 0.5 # fill style

#count and plot
plot "data.dat" u (hist($1,width)):(1.0) smooth freq w boxes lc rgb"green" notitle

Wie üblich ist Gnuplot ein fantastisches Werkzeug für das Plotten süß suchen Grafiken und es kann gemacht werden, alle Arten von Berechnungen durchzuführen. Doch , wird es auf Plotdaten gedacht und nicht als Rechner zu dienen, und es ist oft einfacher, ein externes Programm zu verwenden (zB Octave), die mehr „kompliziert“ Berechnungen zu tun, speichern diese Daten in ein Datei, dann Gnuplot verwenden, um die Grafik zu erzeugen. Für das oben beschriebene Problem, überprüfen Sie die „hist“ -Funktion aus ist [freq,bins]=hist(data) Octave verwenden, dann zeichnen diese in Gnuplot mit

set style histogram rowstacked gap 0
set style fill solid 0.5 border lt -1
plot "./data.dat" smooth freq with boxes

Ich habe diese Diskussion sehr nützlich gefunden, aber ich habe einige „Abrunden“ Probleme erfahren.

Genauer gesagt, eine binwidth von 0,05 verwendet wird, habe ich festgestellt, dass mit den Techniken, die hier oben vorgestellten Datenpunkte, die 0,1 und 0,15 fällt in der gleichen ist lesen. Diese (offensichtlich unerwünschte Verhalten) ist höchstwahrscheinlich aufgrund der „Boden“ Funktion.

Im Folgenden ist mein kleiner Beitrag, um zu versuchen, dies zu umgehen.

bin(x,width,n)=x<=n*width? width*(n-1) + 0.5*binwidth:bin(x,width,n+1)
binwidth = 0.05
set boxwidth binwidth
plot "data.dat" u (bin($1,binwidth,1)):(1.0) smooth freq with boxes

Diese rekursive Methode ist für x> = 0; Man könnte dies mit mehr bedingten Aussagen verallgemeinert etwas noch allgemeinere zu erhalten.

Wir nicht verwenden rekursive Methode benötigen, kann es langsam sein. Meine Lösung wird unter Verwendung einer benutzerdefinierten Funktion rint instesd von Intrinsic-Funktion int oder Boden.

rint(x)=(x-int(x)>0.9999)?int(x)+1:int(x)

Diese Funktion gibt rint(0.0003/0.0001)=3, während int(0.0003/0.0001)=floor(0.0003/0.0001)=2.

Warum? Bitte schauen Sie auf Perl int Funktion und padding Nullen

habe ich eine kleine Änderung an Born2Smile-Lösung.

Ich weiß, dass nicht viel Sinn macht, aber man kann es nur für den Fall möchten. Wenn Ihre Daten integer sind, und Sie müssen einen Schwimmer Binabmessung (vielleicht für den Vergleich mit einem anderen Satz von Daten oder Plot Dichte in feinerem Raster), müssen Sie eine Zufallszahl zwischen 0 und 1 Innen Boden hinzuzufügen. Andernfalls kommt es zu Spikes aufgrund aufrunden Fehler. floor(x/width+0.5) nicht tun, weil es Muster schaffen, die ursprünglichen Daten nicht wahr ist.

binwidth=0.3
bin(x,width)=width*floor(x/width+rand(0))

Im Hinblick auf Binning-Funktionen, ich habe nicht erwartet, das Ergebnis der bisher angebotenen Funktionen. Wenn nämlich meine binwidth 0.001 ist, wurden diese Funktionen die Behälter auf 0,0005 Punkte Zentrierung, während ich fühle es mehr intuitiv die Behälter auf 0.001 Grenzen zentriert zu haben.

Mit anderen Worten, ich möchte muß

Bin 0.001 contain data from 0.0005 to 0.0014
Bin 0.002 contain data from 0.0015 to 0.0024
...

Die Binning-Funktion kam ich mit ist

my_bin(x,width)     = width*(floor(x/width+0.5))

Hier ist ein Skript einige der angebotenen sind Funktionen diesen vergleichen:

rint(x) = (x-int(x)>0.9999)?int(x)+1:int(x)
bin(x,width)        = width*rint(x/width) + width/2.0
binc(x,width)       = width*(int(x/width)+0.5)
mitar_bin(x,width)  = width*floor(x/width) + width/2.0
my_bin(x,width)     = width*(floor(x/width+0.5))

binwidth = 0.001

data_list = "-0.1386 -0.1383 -0.1375 -0.0015 -0.0005 0.0005 0.0015 0.1375 0.1383 0.1386"

my_line = sprintf("%7s  %7s  %7s  %7s  %7s","data","bin()","binc()","mitar()","my_bin()")
print my_line
do for [i in data_list] {
    iN = i + 0
    my_line = sprintf("%+.4f  %+.4f  %+.4f  %+.4f  %+.4f",iN,bin(iN,binwidth),binc(iN,binwidth),mitar_bin(iN,binwidth),my_bin(iN,binwidth))
    print my_line
}

und hier ist der Ausgang

   data    bin()   binc()  mitar()  my_bin()
-0.1386  -0.1375  -0.1375  -0.1385  -0.1390
-0.1383  -0.1375  -0.1375  -0.1385  -0.1380
-0.1375  -0.1365  -0.1365  -0.1375  -0.1380
-0.0015  -0.0005  -0.0005  -0.0015  -0.0010
-0.0005  +0.0005  +0.0005  -0.0005  +0.0000
+0.0005  +0.0005  +0.0005  +0.0005  +0.0010
+0.0015  +0.0015  +0.0015  +0.0015  +0.0020
+0.1375  +0.1375  +0.1375  +0.1375  +0.1380
+0.1383  +0.1385  +0.1385  +0.1385  +0.1380
+0.1386  +0.1385  +0.1385  +0.1385  +0.1390
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top