Question

Je sais comment créer un histogramme (utiliser juste « avec des boîtes ») dans gnuplot si mon fichier .dat a déjà correctement les données mis en cellule. Est-il possible de prendre une liste de numéros et ont gnuplot fournir un histogramme en fonction des plages et bin tailles de l'utilisateur fournit?

Était-ce utile?

La solution

oui, et son rapide et simple mais très cachée:

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

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

vérifier help smooth freq pour voir pourquoi le fait ci-dessus un histogramme

pour faire face à des plages qui se trouve juste la variable xrange.

Autres conseils

J'ai corrections couple / ajouts à réponse très utile de Born2Smile:

  1. bacs vides ont causé la boîte pour le bac adjacent à étendre de façon incorrecte dans son espace; éviter cela en utilisant set boxwidth binwidth
  2. Dans la version de Born2Smile, bacs sont rendus comme centrée sur leur borne inférieure. Strictement ils doivent s'étendre à partir de la borne inférieure à la borne supérieure. Ceci peut être corrigé en modifiant la fonction bin: bin(x,width)=width*floor(x/width) + width/2.0

Soyez très prudent: toutes les réponses sur cette page prennent implicitement la décision de l'endroit où le binning commence - le bord gauche de la gauche la plus bin, si vous aimez - des mains de l'utilisateur. Si l'utilisateur combine l'une de ces fonctions pour binning avec son / sa propre décision sur l'endroit où commence binning (comme cela se fait sur le blog qui est lié ci-dessus), les fonctions sont surtout incorrectes. Avec un point de départ arbitraire pour binning « Min », la fonction correcte est:

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

Vous pouvez voir pourquoi cela est correct en séquence (il aide à tirer quelques poubelles et un point quelque part dans l'un d'entre eux). Soustraire min de votre point de données pour voir dans quelle mesure dans la plage de binning est. Puis diviser par binwidth afin que vous travaillez efficacement en unités de « bacs ». Ensuite, « plancher » le résultat pour aller au bord gauche de ce bac, ajoutez 0,5 à aller au milieu du bac, il faut multiplier par la largeur de sorte que vous n'êtes pas travailler plus longtemps dans les unités de bacs, mais dans une échelle absolue à nouveau, puis enfin rajouter le vous compensez Min soustrait au début.

Considérez cette fonction en action:

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

par exemple. la valeur 1.1 tombe vraiment dans le bac à gauche:

  • cette fonction mappe correctement au centre du bac gauche (0,75);
  • La réponse de Born2Smile, bin (x) = largeur * étage (x / largeur), elle transforme de façon incorrecte à 1;
  • La réponse de MAS90, bin (x) = largeur * étage (x / largeur) + binwidth / 2.0, cartes de façon incorrecte à 1,5.

La réponse de Born2Smile est correcte que si les limites de bin se produisent à (n + 0,5) * binwidth (où n fonctionne sur les entiers). La réponse de MAS90 est correcte que si les limites de bin se produisent à n * binwidth.

Voulez-vous tracer un graphique comme celui-ci? entrer dans la description d'image ici Oui? Ensuite, vous pouvez jeter un oeil à mon article de blog: http: //gnuplot-surprising.blogspot.com/2011/09/statistic-analysis-and-histogram.html

Les lignes clés du 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

Comme d'habitude, Gnuplot est un outil fantastique pour tracer des graphiques à la recherche douce et il peut être fait pour effectuer toutes sortes de calculs. Cependant , il est destiné à tracer des données plutôt que de servir de calculatrice et il est souvent plus facile d'utiliser un programme externe (par exemple, Octave) pour faire les calculs plus « complexes », enregistrer ces données dans un fichier, puis utilisez Gnuplot pour produire le graphique. Pour le problème ci-dessus, consultez la fonction « hist » est Octave en utilisant [freq,bins]=hist(data), puis tracer cela à l'aide Gnuplot

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

J'ai trouvé cette discussion très utile, mais je l'ai connu quelques problèmes « arrondi au large ».

Plus précisément, en utilisant un binwidth de 0,05, j'ai remarqué que, avec les techniques présentées ci-dessus, les points de données qui ont lu 0,1 et 0,15 chute dans le même bac. Ce (comportement évidemment indésirable) est très probablement dû à la fonction « étage ».

Ci-après est ma petite contribution pour essayer de contourner cela.

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

Cette méthode récursive est pour x> = 0; on pourrait généraliser ce avec plus de déclarations conditionnelles pour obtenir quelque chose d'encore plus général.

On n'a pas besoin d'utiliser la méthode récursive, il peut être lent. Ma solution utilise une fonction définie par l'utilisateur de la fonction Rint instesd instrinsic int ou sur le sol.

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

Cette fonction donnera rint(0.0003/0.0001)=3, tandis que int(0.0003/0.0001)=floor(0.0003/0.0001)=2.

Pourquoi? S'il vous plaît regarder Perl fonction int et zéros remplissage

J'ai une petite modification à la solution de Born2Smile.

Je sais que cela ne fait pas beaucoup de sens, mais vous pouvez juste au cas où. Si vos données est un entier et vous avez besoin d'une taille de bac à flotteur (peut-être pour la comparaison avec un autre ensemble de données, ou la densité des parcelles dans la grille plus fine), vous devez ajouter un nombre aléatoire entre 0 et 1 à l'intérieur sol. Dans le cas contraire, il y aura des pics dus à arrondir erreur. floor(x/width+0.5) ne le fera pas, car il va créer modèle qui est pas vrai aux données d'origine.

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

En ce qui concerne les fonctions de binning, je ne m'y attendais le résultat des fonctions offertes à ce jour. A savoir, si mon binwidth est de 0,001, ces fonctions ont été les bacs de centrage sur les points 0,0005, alors que je pense qu'il est plus intuitif d'avoir les bacs centrés sur 0.001 limites.

En d'autres termes, je voudrais avoir

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

La fonction binning je suis venu avec est

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

Voici un script pour comparer certaines des fonctions de bin offertes à celui-ci:

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
}

et est ici la sortie

   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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top