Pregunta

Sé cómo crear un histograma (simplemente use "con cuadros") en gnuplot si mi archivo .dat ya tiene datos agrupados correctamente.¿Hay alguna manera de tomar una lista de números y hacer que gnuplot proporcione un histograma basado en rangos y tamaños de contenedores que proporciona el usuario?

¿Fue útil?

Solución

Sí, y su rápida y sencilla aunque muy escondido:

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

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

echa un vistazo a help smooth freq ver por qué el anterior hace un histograma

para hacer frente a los rangos acaba de establecer la variable xrange.

Otros consejos

Tengo un par de correcciones/adiciones a la muy útil respuesta de Born2Smile:

  1. Los contenedores vacíos causaron que la caja del contenedor adyacente se extendiera incorrectamente en su espacio;evitar esto usando set boxwidth binwidth
  2. En la versión de Born2Smile, los contenedores se representan centrados en su límite inferior.Estrictamente deberían extenderse desde el límite inferior hasta el límite superior.Esto se puede corregir modificando el bin función: bin(x,width)=width*floor(x/width) + width/2.0

Tenga mucho cuidado: todas las respuestas en esta página están tomando implícitamente la decisión de dónde comienza la hurgar en la basura - el borde izquierdo de la bandeja de más a la izquierda, si se quiere - fuera de las manos del usuario. Si el usuario es la combinación de cualquiera de estas funciones para hurgar en la basura de datos con su / su propia decisión acerca de dónde se inicia de agrupación (como se hace en el blog que está vinculado al anterior) las funciones anteriores son incorrectas. Con un punto de partida arbitrario para binning 'Min', la función correcta es:

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

Puede ver por qué esto es correcto secuencialmente (que ayuda a sacar algunas cajas y un punto en alguna parte de uno de ellos). Min restar de su punto de datos para ver hasta qué punto en el rango de hurgar en la basura que es. Luego divida por binwidth por lo que está trabajando efectivamente en unidades de contenedores ''. Entonces 'piso' el resultado de ir hasta el borde izquierdo de que Bin, añadir 0,5 a ir al centro de la papelera, se multiplica por el ancho de manera que ya no estás trabajando en unidades de contenedores pero en una escala absoluta de nuevo, y por último añadir de nuevo en el Min desfase que restan en la salida.

Considere esta función en acción:

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

por ejemplo. el valor de 1,1 verdaderamente cae en la bandeja izquierda:

  • esta función mapea correctamente a la centro de la bandeja izquierda (0,75);
  • respuesta de Born2Smile, bin (x) = width * piso (x / anchura), asigna incorrectamente a 1;
  • respuesta de MAS90, bin (x) = width * piso (x / anchura) + binwidth / 2,0, incorrectamente asigna a 1,5.

La respuesta de Born2Smile sólo es correcta si los límites de basura se producen a (n + 0,5) * binwidth (donde n se ejecuta sobre números enteros). La respuesta de MAS90 sólo es correcta si los límites de basura se producen en n * binwidth.

¿Quieres trazar un gráfico como éste? introducir descripción de la imagen aquí ¿si? A continuación, puede echar un vistazo a mi blog artículo: http: //gnuplot-surprising.blogspot.com/2011/09/statistic-analysis-and-histogram.html

líneas clave del código:

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

Como de costumbre, Gnuplot es una herramienta fantástica para trazar gráficos de mirada dulce y puede ser hecho para realizar todo tipo de cálculos. No obstante , se pretende trazar datos en lugar de servir como una calculadora y que a menudo es más fácil de usar un programa externo (por ejemplo, Octave) para hacer los cálculos más "complicado", guardar estos datos en una archivo, a continuación, utilizar Gnuplot para producir la gráfica. Para el problema anterior, visita la función "hist" se Octave usando [freq,bins]=hist(data), a continuación, trazar esto en Gnuplot utilizando

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

He encontrado esta discusión muy útil, pero he experimentado algunos "redondeo" problemas.

Más precisamente, usando un binwidth de 0,05, he notado que, con las técnicas presentadas aquí anteriormente, los puntos de datos que leen 0,1 y 0,15 caída en el mismo bin. Este (comportamiento obviamente no deseado) es más probable debido a la función de "baja".

De aquí en adelante es mi pequeña contribución para tratar de eludir esto.

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

Este método recursivo es para x> = 0; uno puede generalizar esto con más declaraciones condicionales para obtener algo aún más general.

No es necesario utilizar el método recursivo, puede ser lento. Mi solución es utilizar una función rint instesd definida por el usuario de int función intrínseca o el piso.

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

Esta función permite obtener rint(0.0003/0.0001)=3, mientras int(0.0003/0.0001)=floor(0.0003/0.0001)=2.

¿Por qué? Por favor, mire Perl función int y ceros de relleno

Tengo una pequeña modificación a la solución de Born2Smile.

Sé que no tiene mucho sentido, pero puede que quiera por si acaso. Si los datos son enteros y se necesita un tamaño de bin flotador (tal vez para la comparación con otro conjunto de datos, o la densidad de trama en la malla más fina), tendrá que añadir un número aleatorio entre 0 y 1 en el interior piso. De lo contrario, habrá picos debidos a reunir a error. floor(x/width+0.5) no lo hará porque creará patrón que no es cierto que los datos originales.

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

Con respecto a las funciones de agrupación, que no esperaba el resultado de las funciones ofrecidas hasta ahora. Es decir, si mi binwidth es 0,001, estas funciones fueron centrando en los contenedores de 0,0005 puntos, mientras que siento que es más intuitivo para que los contenedores se centraron en 0.001 límites.

En otras palabras, me gustaría tener

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

La función de agrupación que se me ocurrió es

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

Aquí hay un script para comparar algunas de las funciones de basura que se ofrecen a éste:

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
}

Y aquí está la salida

   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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top