2010-12-07 10 views
11

Tengo 500 archivos para trazar y quiero hacer esto automáticamente. Tengo el script gnuplot que hace el trazado con el nombre del archivo codificado. Me gustaría tener un bucle que llame a gnuplot en cada iteración con un nombre de archivo diferente, pero no parece que gnuplot admita argumentos de línea de comandos.¿Puede Gnuplot tomar argumentos diferentes en tiempo de ejecución? tal vez con Python?

¿Hay alguna manera fácil? También instalé el paquete gnuplot-python en caso de que pueda hacerlo a través de un script de Python. Sin embargo, no pude encontrar la API así que es un poco difícil de entender.

¡Gracias!

Respuesta

22

Puede transformar su script de gnuplot para un script de shell anteponiendo las líneas

#!/bin/sh 
gnuplot << EOF 

añadiendo la línea

EOF 

y sustituyendo cada $ por \$. Luego, puede sustituir cada aparición del nombre de archivo por $1 y llamar al script de shell con el nombre del archivo como parámetro.

+0

Funciona como un amuleto ... ¡gracias! Agregué otro script que realiza un bucle y llama a este gnuplot con un archivo diferente cada vez y eso es todo. – user431336

0

Aquí hay una manera de hacerlo. El archivo de entrada gnuplot, plot.gp decir, contiene una línea

plot "data" 

o algo por el estilo. Guarde las líneas antes de esta línea en plot1.gp y las líneas después de esta línea en plot2.gp. Ahora llamar gnuplot como

gnuplot plot1.gp -e `plot "data"` plot2.gp 

que facilita pasando el nombre del data en la línea de comandos.

+0

Gracias, funciona, pero un pequeño problema. Tengo en las líneas del script gnuplot que usan el nombre del archivo como: set output 'data.png'. Necesito reemplazarlo con el argumento de línea de comando también. – user431336

+0

Por supuesto, podría dividir la secuencia de comandos en aún más archivos, pero tal vez echar un vistazo a mi otra respuesta. –

1

Una forma sencilla es generar secuencias de comandos de gnuplot 500, así:

for filename in list_of_files: 
    outfile = open(filename + '-script', 'w') 
    outfile.write(script_text % (filename,)) 

donde script_text es el texto de su script de gnuplot con el nombre de archivo reemplazado con un %s.

+1

Así que su solución es generar 500 scripts automáticamente y luego escribir un script que llame a gnuplot 500 veces. No es la solución más elegante, pero esto funcionará. ¡Gracias! – user431336

+0

Sí, la elegancia es para las personas que saben lo que hacen. Sé muy poco sobre gnuplot a pesar de haber escrito http://www.nmichaels.org/graph/graphinator.py – nmichaels

0

puedo crear un archivo llamado test.txt contiene plot [0:20] x;

corro gnuplot test.txt y veo que gnuplot ha leído de hecho contenido de mi archivo, por lo que los argumentos de apoyo en tiempo de ejecución.

+0

Eso es verdad. Toma el script gnuplot y lo ejecuta. Sin embargo, mi pregunta es acerca de tomar argumentos para usar en el script gnuplot. Puede que no lo haya explicado muy bien. Gracias. – user431336

6

En cuanto a $ en la solución de Sven Marnach (las líneas entre EOF se llaman "script aquí" en el lenguaje shell): en mi experiencia, uno usa variables de shell como de costumbre, pero $ s que son para gnuplot debe ser escapado.

Aquí se muestra un ejemplo:

for distrib in "uniform" "correlated" "clustered" 
do 
    gnuplot << EOF 
    # gnuplot preamble omitted for brevity 

    set output "../plots/$distrib-$eps-$points.pdf" 
    set title "$distrib distribution, eps = $eps, #points = $points" 

    plot "../plots/dat/$distrib-$eps-$points.dat" using 1:(\$2/$points) title "exact NN" 
EOF 

done 

Nota de la barra invertida de escape al dólar en lo que gnuplot lo ve.

1

He hecho esto algunas veces. Pero no use EOF, porque no puede escribir en bash dentro de las etiquetas < < EOF y EOF. Dependiendo de los nombres de los archivos, puedes hacerlo de diferentes maneras.

a) Si los nombres de los archivos son loopable (tipo 1).dat 3.dat 2.dat, etc.)

#!/bin/bash  
for((i=0;i<1;i++)) do 
    echo "plot '-' u 1:2" 
    for((j=1;j<=3;j++)) do 
    cat $i.dat 
    echo "e" 
    done 
done | gnuplot -persist 

El primer bucle es un tipo de memoria intermedia para alimentar todo a gnuplot.

b) Si los nombres de los archivos no son loopable (como ñlasjkd.dat ajñljd.mov añlsjkd.gif) primero debe moverlos a una nueva carpeta. A continuación, hacer

#!/bin/bash  

ffiles=$(ls | xargs)  # a list of the folder's files 
# Use the list to pipe all the data to gnuplot using cat 
for((i=0;i<1;i++)) do 
    echo "plot '-' u 1:2 w lp"; 
    cat $ffiles; 
    echo "e"; 
done | gnuplot -persist 

c) Si quieres algo más, es decir: para mantener la información de los archivos separados sólo en un archivo ... pero maintaning el uso de hojas de datos vivos "índice" de gnuplot (si lee gnuplot dos líneas negras adivina que es otra ficha técnica)

#!/bin/bash 

ffiles=$(ls|xargs) 
ls $ffiles > ffiles.list # A file with the folder's files 
while read line 
do 
    cat $line; 
    echo -e; echo -e; 
done <ffiles.list> alldata.dat 
# ^-feeding ffiles.list to the while loop 
# and writing the file alldata.dat 

ahora se puede ir a gnuplot y acceso a una ficha técnica

plot 'alldata.dat' index 1 u 1:2 

y verá el primer archivo que aparece en la lista de ffiles" .lista". Si desea ver más de uno, por ejemplo 4

plot 'alldata.dat' index 1:4 u 1:2 

complicado pero fácil.

1

A menos que malinterprete su pregunta, hay una manera más fácil.

En el script gnuplot, reemplace todas las apariciones de su nombre de archivo con $0. A continuación, en bash, un bucle sobre sus archivos de trazado (digamos que son archivos .txt en $ plotsDir) y llame a gnuplot:

for f in "$plotsDir/*.txt"; do 
    echo "call '$f'" | gnuplot 
done 
0

diferentes métodos para resolver este problema también se cubren en How to pass command line argument to gnuplot?:

  • Usando -e
  • Usando -c o call con ARG0 como las variables (gnuplot> = 5)
  • Usando call con $0 igual que las variables (gnuplot < = 4.6.6)
  • El uso de variables de entorno y system()
  • Tubería el programa en gnuplot
Cuestiones relacionadas