Sé cómo crear un histograma (simplemente use "con cuadros") en gnuplot si mi archivo .dat ya tiene datos correctamente agrupados. ¿Hay alguna manera de tomar una lista de números y hacer que gnuplot proporcione un histograma en función de los rangos y tamaños de espacio que el usuario proporciona?¿Histograma usando gnuplot?
Respuesta
sí, y su rápida y sencilla aunque muy ocultos:
binwidth=5
bin(x,width)=width*floor(x/width)
plot 'datafile' using (bin($1,binwidth)):(1.0) smooth freq with boxes
la salida help smooth freq
para ver por qué el anterior hace un histograma
para hacer frente a los rangos acaba de establecer la variable xrange.
Creo que la respuesta de @ ChrisW a continuación trae un punto importante a tener en cuenta para cualquiera que quiera hacer un Histograma en Gnuplot. – Abhinav
Tenga mucho cuidado, esto solo funciona si no hay un contenedor "perdido" en el conjunto ... Esta función corrige el valor y de un contenedor perdido al valor y del contenedor anterior no perdido. ¡Esto puede ser muy engañoso! – PinkFloyd
I tienen un par de correcciones/adiciones a respuesta muy útil del Born2Smile:
- contenedores vacíos causados la caja para el bin adyacente a extender incorrectamente en su espacio; evite esto usando
set boxwidth binwidth
- En la versión de Born2Smile, los contenedores se muestran centrados en su límite inferior. Estrictamente, deberían extenderse desde el límite inferior al límite superior. Esto se puede corregir mediante la modificación de la función
bin
:bin(x,width)=width*floor(x/width) + binwidth/2.0
En realidad, esa segunda parte debe ser 'bin (x, ancho) = ancho * piso (x/ancho) + binwidth/2.0' (cálculos de punto flotante) – bgw
Quiere decir' bin (x, ancho) = ancho * piso (x/ancho) + ancho/2.0'. Si estamos pasando 'ancho' como un argumento, entonces úselo. :-) – Mitar
@mgilson, creo que la respuesta de ChrisW aporta una importante corrección a esta respuesta. – Abhinav
¿Quieres trazar un gráfico como éste? ¿sí? A continuación, puede echar un vistazo a mi artículo de blog: 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
he encontrado esta discusión muy útil, pero he experimentado algunos "redondeo" problemas.
Más precisamente, usando un ancho de contenedor de 0.05, he notado que, con las técnicas presentadas aquí arriba, los puntos de datos que leen 0.1 y 0.15 caen en la misma ubicación. Esto (comportamiento obviamente no deseado) se debe probablemente a la función "piso".
De ahora 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 podría 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 está utilizando una función definida por el usuario rint instesd de la función intrínseca int o floor.
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é? Consulte Perl int function and padding zeros
Tenga mucho cuidado: todas las respuestas en esta página toman implícitamente la decisión de dónde comienza el binning, el borde izquierdo del contenedor más a la izquierda, si lo desea, fuera del usuario. manos. Si el usuario combina cualquiera de estas funciones para agrupar datos con su propia decisión sobre dónde comienza el binning (como se hace en el blog al que se ha vinculado anteriormente), las funciones anteriores son todas incorrectas.Con un punto de partida arbitrario para hurgar en la basura 'Min', la función correcta es:
bin(x) = width*(floor((x-Min)/width)+0.5) + Min
Usted puede ver por qué esto es correcto secuencialmente (que ayuda a sacar algunas cajas y un punto en alguna parte de uno de ellos). Reste Min de su punto de datos para ver qué tan lejos está dentro del rango de binning. Luego divide por binwidth para que estés trabajando efectivamente en unidades de 'bins'. Luego, 'fondo' el resultado para ir al borde izquierdo de ese contenedor, agregue 0.5 para ir al medio del contenedor, multiplique por el ancho para que ya no trabaje en unidades de contenedores, sino en una escala absoluta nuevamente, luego, vuelva a agregar el desplazamiento Min que resta al inicio.
considerar 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 1.1 cae realmente en el contenedor izquierdo:
- esta función lo ubica correctamente en el centro del contenedor izquierdo (0.75);
- La respuesta de Born2Smile, bin (x) = ancho * piso (x/ancho), lo mapea incorrectamente en 1;
- respuesta mas90, bin (x) = ancho * piso (x/ancho) + binwidth/2.0, lo mapea incorrectamente en 1.5.
La respuesta de Born2Smile es correcta solo si los límites del contenedor se producen en (n + 0.5) * binwidth (donde n se ejecuta sobre enteros). La respuesta de mas90 solo es correcta si los límites del contenedor se producen en n * binwidth.
+1 para prestar atención a los detalles ... gracias – Abhinav
Tengo una pequeña modificación en la solución de Born2Smile.
Sé que no tiene mucho sentido, pero es posible que lo desee por si acaso. Si sus datos son enteros y necesita un tamaño de contenedor flotante (tal vez para comparar con otro conjunto de datos, o densidad de trazado en una cuadrícula más fina), necesitará agregar un número aleatorio entre 0 y 1 dentro del piso. De lo contrario, habrá picos debido al error de redondeo. floor(x/width+0.5)
no funcionará porque creará un patrón que no es verdadero para los datos originales.
binwidth=0.3
bin(x,width)=width*floor(x/width+rand(0))
¡Eso no tiene ningún sentido! – Christoph
No ha encontrado tales situaciones, pero puede hacerlo más tarde. Puede probarlo con enteros normalmente distribuidos con una sd flotante y trazar histogramas con bin = 1, y bin = s.d. Vea lo que obtiene con y sin el truco rand (0). Capté un error de un colaborador al revisar su manuscrito. Sus resultados cambiaron de absolutamente tonterías a una bella figura como se esperaba. – path4
Ok, tal vez la explicación es tan breve, que uno no puede entenderlo sin un caso de prueba más concreto. Haré una pequeña edición de tu respuesta para poder deshacer el voto a la baja;) – Christoph
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. Sin embargo, está diseñado para trazar datos en lugar de servir como una calculadora y a menudo es más fácil usar un programa externo (por ejemplo, Octave) para hacer cálculos más "complicados", guardar estos datos en un archivo y luego usar Gnuplot para producir el gráfico. Para el problema anterior, echa un vistazo a la función "hist" es Octave usando [freq,bins]=hist(data)
, a continuación, una de sus parcelas en Gnuplot usando
set style histogram rowstacked gap 0
set style fill solid 0.5 border lt -1
plot "./data.dat" smooth freq with boxes
Con respecto a las funciones se van a agrupar, yo no esperaba que el resultado de las funciones ofrecidas hasta ahora. A saber, si mi ancho de banda es 0.001, estas funciones estaban centrando los contenedores en 0.0005 puntos, mientras que creo que es más intuitivo tener los contenedores centrados en los límites de 0.001.
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í es 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
- 1. añadiendo barra de error del histograma de la gnuplot
- 2. Histograma apilado de Gnuplot en blanco y negro
- 3. Histograma sin función de trazado
- 4. Cómo crear un histograma usando MySQL
- 5. comparando dos imágenes usando el histograma
- 6. aplicación C++ usando qt, cómo incluir gnuplot
- 7. Histograma Matplotlib
- 8. Histograma básico en JFreeChart
- 9. Cómo dibujar el histograma usando EmguCV y C#
- 10. gnuplot: la leyenda se oculta detrás de los datos
- 11. Hacer películas con archivos de datos usando gnuplot
- 12. Gnuplot: Histogramas apilados múltiples, cada grupo usando la misma clave
- 13. Histograma de imagen OpenCL
- 14. El uso de gnuplot para histogramas apilados
- 15. histograma en jfreechart
- 16. Trazar histograma en Python
- 17. Histograma en el enrejado
- 18. histograma sin líneas verticales
- 19. Cómo crear un histograma
- 20. gnuplot con errorbars trazado
- 21. Gnuplot resolución eje x
- 22. Alejar en Octave/gnuplot
- 23. gnuplot para agrupar múltiples barras
- 24. Gnuplotte cambia el color de las barras en el histograma
- 25. Dibujando histograma en OpenCV-Python
- 26. gnuplot linecolor variable en matplotlib?
- 27. gnuplot funcionalidad epslatex en matplotlib
- 28. generar histograma desde el archivo
- 29. ¿Cómo mantener un histograma dinámico?
- 30. Histograma nude de matrices grandes
Si no obtiene una respuesta, existen otras herramientas destinadas a hacer tales cosas. Yo uso Root (http://root.cern.ch/) muchos otros por aquí usan R, y hay al menos algunas otras opciones. – dmckee
¿qué es bin y qué es binned? –