220 votes

Histogramme avec gnuplot ?

Je sais comment créer un histogramme (en utilisant simplement "with boxes") dans gnuplot si mon fichier .dat contient déjà des données correctement binées. Existe-t-il un moyen de prendre une liste de nombres et de faire en sorte que gnuplot fournisse un histogramme basé sur des plages et des tailles de boîtes fournies par l'utilisateur ?

2 votes

Si vous n'obtenez pas de réponse, il existe d'autres outils destinés à faire ce genre de choses. J'utilise Root ( Root.cern.ch ) beaucoup d'autres ici utilisent R, et il y a au moins quelques autres options.

1 votes

La case est la plage de valeurs rassemblées pour chaque barre de l'histogramme. Chaque case a une limite inférieure et une limite supérieure, et toutes les données dont la valeur se situe dans cette fourchette sont comptabilisées pour cette barre. Binné signifie que mon fichier de données est déjà organisé en fonction du nombre de points de données compris dans chaque bin et qu'il est donc prêt à être représenté sous la forme d'un histogramme.

243voto

Born2Smile Points 1485

Oui, et c'est rapide et simple, bien que très caché :

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 comprendre pourquoi l'exemple ci-dessus produit un histogramme

pour traiter les plages, il suffit de définir la variable xrange.

13 votes

Je pense que la réponse de @ChrisW ci-dessous met en évidence un point important pour tous ceux qui veulent créer un histogramme dans Gnuplot.

4 votes

Attention, cela ne fonctionne que s'il n'y a pas d'emplacement "manquant" dans le lot... Cette fonction fixe la valeur y d'une case manquante à la valeur y de la case non manquante précédente. Cela peut être très trompeur !!!

1 votes

J'ajouterais set boxwidth binwidth au dessus. Cela m'a beaucoup aidé.

98voto

mas90 Points 651

J'ai quelques corrections/compléments à apporter à la réponse très utile de Born2Smile :

  1. Les bacs vides ont provoqué une extension incorrecte de la boîte du bac adjacent dans son espace. set boxwidth binwidth
  2. Dans la version de Born2Smile, les cellules sont centrées sur leur limite inférieure. Strictement, ils devraient s'étendre de la borne inférieure à la borne supérieure. Ceci peut être corrigé en modifiant le paramètre bin fonction : bin(x,width)=width*floor(x/width) + width/2.0

10 votes

En fait, la deuxième partie devrait être bin(x,width)=width*floor(x/width) + binwidth/2.0 (calculs en virgule flottante)

8 votes

Vous voulez dire bin(x,width)=width*floor(x/width) + width/2.0 . Si nous passons width comme argument, puis l'utiliser :-)

87voto

ChrisW Points 300

Soyez très prudent : toutes les réponses données sur cette page enlèvent implicitement à l'utilisateur la décision de savoir où commence le classement - le bord gauche du bac le plus à gauche, si vous voulez -. Si l'utilisateur combine l'une de ces fonctions de regroupement des données avec sa propre décision concernant le point de départ du regroupement (comme le fait le blog dont le lien figure ci-dessus), les fonctions ci-dessus sont toutes incorrectes. Avec un point de départ arbitraire pour la classification "Min", la fonction correcte est :

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

Vous pouvez voir pourquoi cela est correct de manière séquentielle (il est utile de dessiner quelques bacs et un point quelque part dans l'un d'entre eux). Soustrayez Min de votre point de données pour voir à quelle distance de la plage de binages il se trouve. Divisez ensuite par la largeur de la cellule afin de travailler en unités de "cellules". Ensuite, "planifiez" le résultat pour atteindre le bord gauche de cette cellule, ajoutez 0,5 pour atteindre le milieu de la cellule, multipliez par la largeur pour ne plus travailler en unités de cellules mais en échelle absolue, et enfin ajoutez le décalage Min que vous avez soustrait au début.

Cette fonction est à l'œuvre :

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 se trouve vraiment dans la case de gauche :

  • cette fonction l'affecte correctement au centre de l'emplacement gauche (0,75) ;
  • La réponse de Born2Smile, bin(x)=largeur*floor(x/largeur), l'associe incorrectement à 1 ;
  • La réponse de mas90, bin(x)=width*floor(x/width) + binwidth/2.0, correspond incorrectement à 1.5.

La réponse de Born2Smile n'est correcte que si les limites des cases se situent à (n+0,5)*largeur des cases (où n s'étend sur des entiers). La réponse de mas90 n'est correcte que si les limites des cases se situent à n*largeur des cases.

57voto

hsxz Points 512

Voulez-vous tracer un graphique comme celui-ci ? enter image description here oui ? Dans ce cas, vous pouvez consulter l'article de mon blog : http://gnuplot-surprising.blogspot.com/2011/09/statistic-analysis-and-histogram.html

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

7voto

Alex Points 61

J'ai trouvé cette discussion extrêmement utile, mais j'ai rencontré quelques problèmes d'arrondi.

Plus précisément, en utilisant une largeur de bac de 0,05, j'ai remarqué qu'avec les techniques présentées ci-dessus, les points de données qui se lisent 0,1 et 0,15 tombent dans le même bac. Ce comportement (évidemment indésirable) est très probablement dû à la fonction "floor".

Voici ma petite contribution pour tenter de contourner ce problème.

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 s'applique à x >=0 ; on pourrait la généraliser en utilisant davantage d'énoncés conditionnels pour obtenir quelque chose d'encore plus général.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X