¿Cómo puedo hacer un diagrama gráfico de una secuencia de números a partir de la entrada estándar?

38

Si tengo un archivo de texto largo y quiero mostrar todas las líneas en las que se produce un patrón determinado, hago:

grep -n form innsmouth.txt | cut -d : -f1

Ahora, tengo una secuencia de números (un número por línea)

Me gustaría hacer una representación gráfica en 2D con la aparición en el eje xy el número de línea en el eje y. ¿Cómo puedo conseguir esto?

ingrese la descripción de la imagen aquí

Abdul Al Hazred
fuente
1
¿Podría explicar qué quiere decir con ocurrencia? ¿Quiere decir cuántas veces se encuentra un número particular en el archivo? ¿O simplemente desea el valor real del número en el eje xy el número de línea en el que se encontró ese número en el eje y?
terdon
Quiero decir, por ocurrencia, simplemente en qué orden se encontró un patrón. por ejemplo: primera vez en la línea 400, segunda vez en la línea 410, tercera vez en la línea 412 ...
Abdul Al Hazred

Respuestas:

44

Podrías usar gnuplotpara esto:

 primes 1 100 |gnuplot -p -e 'plot "/dev/stdin"'

produce algo como

ingrese la descripción de la imagen aquí

Puede configurar la apariencia del gráfico para deleite de su corazón, salida en varios formatos de imagen, etc.

Nate Eldredge
fuente
2
Descargué gnuplot e intenté probarlo ingresando: seq 100 | gnuplot -p -e 'plot "/ dev / stdin"'. curiosamente no apareció un gráfico, pero el código de salida (echo $?) fue 0, por lo que tampoco apareció ningún error.
Abdul Al Hazred
@AbdulAlHazred, ¿instaló gnuploto gnuplot-x11? si es el primero, afaik solo proporciona salida de archivos (es decir, generar archivos pdf, png, etc. ) en lugar de trazados interactivos directamente a la pantalla.
steeldriver
@AbdulAlHazred: ¿Qué sucede si solo lo hace seq 100 >seq.dat, luego se ejecuta de forma gnuplotinteractiva y en el tipo de solicitud plot "seq.dat"?
Nate Eldredge
@steeldriver Tengo un error Failed to initialize wxWidgets.con gnuplot-x11 ... ¿Necesito tener uno u otro? o puede ambos gnuploty gnuplot-x11ser instalado?
3kstc
1
Muy agradable; Añadir notitlea la trama sin el título.
Victoria Stuart
13

Me gustaría hacer esto en R. Deberá instalarlo, pero debe estar disponible en los repositorios de sus distribuciones. Para sistemas basados ​​en Debian, ejecute

sudo apt-get install r-base

Eso también debería traer, r-base-corepero si no lo hace, corre sudo apt-get install r-base-coretambién. Una vez que haya Rinstalado, puede escribir un script R simple para esto:

#!/usr/bin/env Rscript
args <- commandArgs(TRUE)
## Read the input data
a<-read.table(args[1])
## Set the output file name/type
pdf(file="output.pdf")
## Plot your data
plot(a$V2,a$V1,ylab="line number",xlab="value")
## Close the graphics device (write to the output file)
dev.off()

El script anterior creará un archivo llamado output.pdf. Probé de la siguiente manera:

## Create a file with 100 random numbers and add line numbers (cat -n)
for i in {1..100}; do echo $RANDOM; done | cat -n > file 
## Run the R script
./foo.R file

En los datos aleatorios que utilicé, eso produce:

ingrese la descripción de la imagen aquí

No estoy completamente seguro de lo que quiere trazar, pero eso al menos debería apuntarlo en la dirección correcta.

terdon
fuente
Mi Rscript v3.4.4 genera plots.pdf por defecto, independientemente de si usa ggplot o plot.
Vorac
@Vorac, ¿querías comentar otra respuesta? ¿Qué tiene que ver ggplot con él? ¿Y por qué es relevante el nombre de archivo de salida predeterminado?
terdon
En mi sistema Debian, este subconjunto de su script es suficiente #!/usr/bin/env Rscript; args <- commandArgs(TRUE); a<-read.table(args[1]); plot(a$V2,a$V1,ylab="line number",xlab="value");para generar un Rplots.pdf en el mismo directorio.
Vorac
1
@ Vorac sí, por supuesto. Pero quiero elegir el nombre del archivo de salida. Y, lo que es más importante, muestre cómo se puede hacer para que se pueda programar. De lo contrario, cada vez que ejecute un RScript, usará el mismo nombre y sobrescribirá la salida de una ejecución preciosa.
terdon
11

Si es posible que una impresión de terminal muy simple sea suficiente, y que pueda estar satisfecho con los ejes invertidos, considere lo siguiente:

seq 1000   |
grep -n 11 |
while IFS=: read -r n match
do  printf "%0$((n/10))s\n" "$match"
done

Los gráficos anteriores muestran una tendencia invertida en una escala del 10% para cada aparición del patrón 11 en la salida de seq 1000.

Me gusta esto:

11
        110
        111
        112
        113
        114
        115
        116
        117
        118
        119
                  211
                            311
                                      411
                                                511
                                                          611
                                                                    711
                                                                              811
                                                                                        911

Con puntos y recuento de ocurrencias podría ser:

seq 1000    |
grep -n 11  | {
i=0
while IFS=: read -r n match
do    printf "%02d%0$((n/10))s\n" "$((i+=1))" .
done; }

... que imprime ...

01 .
02           .
03           .
04           .
05           .
06           .
07           .
08           .
09           .
10           .
11           .
12                     .
13                               .
14                                         .
15                                                   .
16                                                             .
17                                                                       .
18                                                                                 .
19                                                                                           .

Podría obtener los ejes como su ejemplo con mucho más trabajo y tput: necesitaría hacer el \033[Aescape (o su equivalente, ya que es compatible con su emulador de terminal) para mover el cursor una línea hacia arriba cada vez.

Si awkes printfcompatible con el relleno de espacio como lo hace el shell POSIX printf, puede usarlo para hacer lo mismo, y probablemente también de manera mucho más eficiente. Yo, sin embargo, no sé cómo usarlo awk.

mikeserv
fuente
1

Mejorar la respuesta de Nate para tener salida en PDF y trazar líneas (requiere el rsvg-convert):

| gnuplot -p -e 'set term svg; set output "|rsvg-convert -f pdf -o out.pdf /dev/stdin"; plot "/dev/stdin" with lines'
Feuerstein
fuente
0

O puede redirigir los datos stdout a través de la tubería a un script de python personalizado. Esto le permitirá una inmensa cantidad de personalización y flexibilidad para analizar, preprocesar y visualizar los datos.

Aquí hay un tutorial sobre esto que escribí para hacer exactamente lo que pretendes. enlazar

cuarzofun
fuente