¿Cómo pasar el argumento de la línea de comando a gnuplot?

148

Quiero usar gnuplot para dibujar figuras del archivo de datos, digamos foo.data . Actualmente, codifiqué el nombre del archivo de datos en el archivo de comandos, digamos foo.plt , y ejecuté el comando gnuplot foo.plgpara trazar datos. Sin embargo, quiero pasar el nombre del archivo de datos como un argumento de comando, por ejemplo, ejecutar un comando gnuplot foo.plg foo.data. ¿Cómo analizar los argumentos de la línea de comandos en el archivo de script gnuplot? Gracias.

Yun Huang
fuente

Respuestas:

191

Puede ingresar variables a través del interruptor -e

$ gnuplot -e "filename='foo.data'" foo.plg

En foo.plg puedes usar esa variable

$ cat foo.plg 
plot filename
pause -1

Para hacer que "foo.plg" sea un poco más genérico, use un condicional:

if (!exists("filename")) filename='default.dat'
plot filename
pause -1

Tenga en cuenta que -etiene que preceder al nombre del archivo; de lo contrario, el archivo se ejecuta antes de las -edeclaraciones. En particular, ejecutar un shebang gnuplot #!/usr/bin/env gnuplotcon ./foo.plg -e ...argumentos CLI ignorará el uso de los argumentos proporcionados.

Jari Laamanen
fuente
20
Esto también se puede usar ifpara suministrar valores predeterminados. if ! exists("filename") filename='default.data'
mgilson
10
Para las personas que ahora se topan con esto, el comentario de mgilson y el parche 3 de Gnuplot 4.6 requieren en if (!exists("filename")lugar de if ! exists("filename").
Sam Mussmann
¿Cómo hacer lo mismo en Windows?
padawan
66
@Chong: puede unirlos o darles a cada uno un -eargumento, por ejemplo, -e "filename='default.data'; foo='bar'"o -e "filename='default.data'" -e "foo='bar"'.
Thor
1
Nota: La -e ...opción tiene que preceder al nombre del archivo. De hecho man gnuplot, podemos leer: -e"lista de comandos" ejecuta los comandos solicitados antes de cargar el siguiente archivo de entrada . .
Hastur
57

Puede pasar argumentos a un script gnuplot desde la versión 5.0, con la bandera -c. Estos argumentos se accede a través de las variables ARG0a ARG9, ARG0siendo el guión, y ARG1para ARG9las variables de cadena. El número de argumentos viene dado por ARGC.

Por ejemplo, el siguiente script ("script.gp")

#!/usr/local/bin/gnuplot --persist

THIRD=ARG3
print "script name        : ", ARG0
print "first argument     : ", ARG1
print "third argument     : ", THIRD 
print "number of arguments: ", ARGC 

puede ser llamado como:

$ gnuplot -c script.gp one two three four five
script name        : script.gp
first argument     : one
third argument     : three
number of arguments: 5

o dentro de gnuplot como

gnuplot> call 'script.gp' one two three four five
script name        : script.gp
first argument     : one
third argument     : three
number of arguments: 5

En gnuplot 4.6.6 y versiones anteriores, existe un callmecanismo con una sintaxis diferente (ahora obsoleta). Los argumentos se accede a través de $#, $0, ..., $9. Por ejemplo, el mismo script anterior se ve así:

#!/usr/bin/gnuplot --persist

THIRD="$2"
print "first argument     : ", "$0"
print "second argument    : ", "$1"
print "third argument     : ", THIRD
print "number of arguments: ", "$#"

y se llama dentro de gnuplot como (recuerde, versión <4.6.6)

gnuplot> call 'script4.gp' one two three four five
first argument     : one
second argument    : two
third argument     : three
number of arguments: 5

Observe que no hay una variable para el nombre del script, por lo que $0es el primer argumento, y las variables se llaman entre comillas. No hay forma de usar esto directamente desde la línea de comandos, solo a través de trucos como el sugerido por @ con-fu-se.

vagoberto
fuente
Traté de usar el -cinterruptor con un script que contiene líneas como plot 'data' using 0:($1/100). gnuplotmuere con la expresión inválida de error porque $1desaparece. Donde me equivoco Tenga en cuenta que sin -c, el script se ejecuta con éxito.
lorcap
Lo probé gnuplot 5.0agregando a estos ejemplos una línea como plot 'data' using 0:($1/100), y no obtuve lo que dices. Sería raro, ya que esta versión define las variables ARG0- ARG9y no $1- $9. Supongo que también tiene la versión 5.0 (¿verdad?), Ya que el -cindicador no es compatible con versiones anteriores. Necesitaría ver un script mínimo para ver dónde está el verdadero problema: /
vagoberto
Estoy corriendo gnuplot 5.0 patchlevel 0bajo Cygwin . El script de una línea print ARG1; plot 'data' using 0:($1/100)imprime correctamente el valor pasado como ARG1y luego sale con la expresión inválida de error apuntando a la barra diagonal print ARG1; plot 'data' using 0:(/100).
lorcap
27

También puede pasar información a través del entorno como se sugiere aquí . El ejemplo de Ismail Amin se repite aquí:

En la cáscara:

export name=plot_data_file

En un script de Gnuplot:

#! /usr/bin/gnuplot

name=system("echo $name")
set title name
plot name using ($16 * 8):20 with linespoints notitle
pause -1
Thor
fuente
66
En lugar de exportar, puede escribir name=plot_data_file ./the_gnuplot_script.
Edgar Bonet
@Edgar Bonet: ¿Qué versión de gnuplot se requiere para esto? No parece funcionar en una máquina que usa 4.2 ...
Bjoern
Hola @Bjoern! Estoy usando Gnuplot 4.6, pero esta no es una característica de Gnuplot, es una característica del shell: name=value commandle dice al shell que ejecute el comando con esa variable en particular en su entorno. Estoy usando bash 4.3.11, pero creo que es una característica de shell muy común.
Edgar Bonet
23

La respuesta de Jari Laamanen es la mejor solución. Solo quiero explicar cómo usar más de 1 parámetro de entrada con variables de shell:

output=test1.png
data=foo.data
gnuplot -e "datafile='${data}'; outputname='${output}'" foo.plg

y foo.plg:

set terminal png
set outputname 
f(x) = sin(x)
plot datafile

Como puede ver, se pasan más parámetros con punto y coma (como en los scripts bash), pero las variables de cadena NECESITAN encapsularse con '' (sintaxis gnuplot, sintaxis Bash)

Mo3bius
fuente
1
Para gnuplot en sí, no importa si usa 'o "para cadenas. Las comillas externas alrededor del -eargumento deben ser "para tener las variables bash sustituidas. Lo siguiente también funciona bien:OUTPUT=foobar; gnuplot -e "output=\"$OUTPUT\"; print output"
Christoph
Gracias por confirmar que puedo usar punto y coma para dividir comandos. Ninguna de las otras respuestas muestra esto.
tommy.carstensen
14

Puede usar truco en entorno unix / linux:

  1. en el programa gnuplot: trama "/ dev / stdin" ...

  2. En la línea de comando: gnuplot program.plot <data.dat

arto
fuente
12

Esta pregunta está bien respondida, pero creo que puedo encontrar un nicho para llenar aquí independientemente, aunque solo sea para reducir la carga de trabajo de alguien que busque en Google esto como lo hice yo. La respuesta de vagoberto me dio lo que necesitaba para resolver mi versión de este problema y compartiré mi solución aquí.

Desarrollé un guión de trama en un entorno actualizado que me permitió hacer:

#!/usr/bin/gnuplot -c 
set terminal png truecolor transparent crop
set output ARG1
set size 1, 0.2
rrLower = ARG2
rrUpper = ARG3
rrSD = ARG4
resultx = ARG5+0 # Type coercion required for data series
resulty = 0.02 # fixed
# etc.

Esto se ejecuta perfectamente bien desde la línea de comandos en un entorno con un gnuplot reciente (5.0.3 en mi caso).

$ ./plotStuff.gp 'output.png' 2.3 6.7 4.3 7

Cuando se cargó en mi servidor y se ejecutó, falló porque la versión del servidor era 4.6.4 (actual en Ubuntu 14.04 LTS). La cuña a continuación resolvió este problema sin requerir ningún cambio en el script original.

#!/bin/bash
# GPlot v<4.6.6 doesn't support direct command line arguments.
#This script backfills the functionality transparently.
SCRIPT="plotStuff.gp"
ARG1=$1
ARG2=$2
ARG3=$3
ARG4=$4
ARG5=$5
ARG6=$6

gnuplot -e "ARG1='${ARG1}'; ARG2='${ARG2}'; ARG3='${ARG3}'; ARG4='${ARG4}'; ARG5='${ARG5}'; ARG6='${ARG6}'" $SCRIPT

La combinación de estos dos scripts permite que los parámetros pasen de scripts bash a gnuplot sin tener en cuenta la versión de gnuplot y básicamente en cualquier * nix.

bp.
fuente
5

Incluso podrías hacer algo de magia de concha, por ejemplo, así:

#!/bin/bash
inputfile="${1}" #you could even do some getopt magic here...

################################################################################
## generate a gnuplotscript, strip off bash header
gnuplotscript=$(mktemp /tmp/gnuplot_cmd_$(basename "${0}").XXXXXX.gnuplot)

firstline=$(grep -m 1 -n "^#!/usr/bin/gnuplot" "${0}")
firstline=${firstline%%:*} #remove everything after the colon
sed -e "1,${firstline}d" < "${0}" > "${gnuplotscript}"


################################################################################
## run gnuplot
/usr/bin/gnuplot -e "inputfile=\"${inputfile}\"" "${gnuplotscript}"
status=$?
if [[ ${status} -ne 0 ]] ; then
  echo "ERROR: gnuplot returned with exit status $?"
fi

################################################################################
## cleanup and exit
rm -f "${gnuplotscript}"
exit ${status}

#!/usr/bin/gnuplot
plot inputfile using 1:4 with linespoints
#... or whatever you want

Mi implementación es un poco más compleja (por ejemplo, reemplazar algunas fichas mágicas en la llamada sed, mientras ya estoy en eso ...), pero simplifiqué este ejemplo para una mejor comprensión. También podría hacerlo aún más simple ... YMMV.

Stefan
fuente
4

En el shell escribe

gnuplot -persist -e "plot filename1.dat,filename2.dat"

y consecutivamente los archivos que quieras. -persist se usa para hacer que la pantalla gnuplot permanezca siempre que el usuario no salga de ella manualmente.

Aniruddha Bera
fuente
En la consola Win7, la opción -persist parece no funcionar. Por ejemplo, gnuplot -persist -c "myscript.plt" "mydata.csv" "myoutput.png"este comando funciona bien y obtengo el archivo "myoutput.png" como espero, pero la pantalla gnuplot no aparece (NO hay exitcomando en myscript.plt). ¿Por qué? ¿Y cómo hacer que la pantalla gnuplot se muestre en mi ejemplo?
lyl
1

Otra forma más es esta:

Tiene un script gnuplot llamado scriptname.gp:

#!/usr/bin/gnuplot -p
# This code is in the file 'scriptname.gp'
EPATH = $0
FILENAME = $1 

plot FILENAME

Ahora puede llamar al script gnuplot scriptname.gppor esta complicada sintaxis de paz:

echo "call \"scriptname.gp\" \"'.'\" \"'data.dat'\"" | gnuplot 
confundir
fuente
0

La respuesta de @ vagoberto parece la mejor en mi humilde opinión si necesita argumentos posicionales , y tengo una pequeña mejora para agregar.

sugerencia de vagoberto:

#!/usr/local/bin/gnuplot --persist

THIRD=ARG3
print "script name        : ", ARG0
print "first argument     : ", ARG1
print "third argument     : ", THIRD 
print "number of arguments: ", ARGC 

que recibe la llamada de:

$ gnuplot -c script.gp one two three four five
script name        : script.gp
first argument     : one
third argument     : three
number of arguments: 5

para esos tipos flojos como yo, uno podría hacer que el script sea ejecutable ( chmod 755 script.gp)

luego use lo siguiente:

#!/usr/bin/env gnuplot -c

THIRD=ARG3
print "script name        : ", ARG0
print "first argument     : ", ARG1
print "third argument     : ", THIRD
print "number of arguments: ", ARGC

y ejecutarlo como:

$ ./imb.plot a b c d
script name        : ./imb.plot
first argument     : a
third argument     : c
number of arguments: 4
Brett Holman
fuente