web-dev-qa-db-fra.com

Comment passer un argument en ligne de commande à gnuplot?

Je veux utiliser gnuplot pour dessiner une figure à partir d'un fichier de données, disons foo.data. Actuellement, j'ai codé en dur le nom du fichier de données dans le fichier de commande, disons foo.plt, et j'exécute la commande gnuplot foo.plg pour tracer les données. Cependant, je souhaite passer le nom du fichier de données en tant qu'argument de commande, par exemple. commande en cours d'exécution gnuplot foo.plg foo.data. Comment analyser les arguments de la ligne de commande dans un fichier script gnuplot? Merci.

136
Yun Huang

Vous pouvez saisir des variables via le commutateur -e

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

Dans foo.plg, vous pouvez ensuite utiliser cette variable

$ cat foo.plg 
plot filename
pause -1

Pour rendre "foo.plg" un peu plus générique, utilisez un conditionnel:

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

Notez que -e doit précéder le nom du fichier, sinon le fichier sera exécuté avant les instructions -e. En particulier, l'exécution d'un gnuplot Shebang #!/usr/bin/env gnuplot avec ./foo.plg -e ... Les arguments de la CLI ignorent l'utilisation des arguments fournis.

176
Jari Laamanen

Vous pouvez passer des arguments à un script gnuplot depuis la version 5.0, avec l'indicateur -c. Ces arguments sont accessibles via les variables ARG0 à ARG9, ARG0 étant le script et ARG1 à ARG9 variables de chaîne. Le nombre d'arguments est donné par ARGC.

Par exemple, le script suivant ("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 

peut être appelé comme:

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

ou dans gnuplot comme

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

Dans gnuplot 4.6.6 et les versions antérieures, il existe un mécanisme call avec une syntaxe différente (maintenant dépréciée). Les arguments sont accessibles via $#, $0, ..., $9. Par exemple, le même script ci-dessus ressemble à:

#!/usr/bin/gnuplot --persist

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

et il est appelé dans gnuplot en tant que (rappelez-vous, version <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

Notez qu'il n'y a pas de variable pour le nom du script, donc $0 est le premier argument et les variables sont appelées entre guillemets. Il n’ya aucun moyen de l’utiliser directement à partir de la ligne de commande, mais uniquement à travers des astuces comme celle suggérée par @ con-fu-se.

46
vagoberto

Vous pouvez également transmettre des informations via l'environnement, comme suggéré ici . L'exemple de Ismail Amin est répété ici:

Dans la coquille:

export name=plot_data_file

Dans un script Gnuplot:

#! /usr/bin/gnuplot

name=system("echo $name")
set title name
plot name using ($16 * 8):20 with linespoints notitle
pause -1
26
Thor

La réponse de Jari Laamanen est la meilleure solution. Je veux juste expliquer comment utiliser plus d'un paramètre d'entrée avec des variables Shell:

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

et foo.plg:

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

Comme vous pouvez le constater, davantage de paramètres sont transmis avec des points-virgules (comme dans les scripts bash), mais les variables de chaîne doivent être encapsulées avec '' (syntaxe gnuplot, syntaxe NOT Bash).

22
Mo3bius

Vous pouvez utiliser un truc dans l’environnement unix/linux:

  1. dans le programme gnuplot: plot "/ dev/stdin" ...

  2. En ligne de commande: gnuplot program.plot <data.dat

14
arto

Cette question a reçu une réponse satisfaisante, mais je pense pouvoir trouver un créneau à combler ici, ne serait-ce que pour réduire la charge de travail de quelqu'un cherchant sur Google comme je l'ai fait. La réponse de vagoberto m'a donné ce dont j'avais besoin pour résoudre ma version de ce problème et je vais donc partager ma solution ici.

J'ai développé un script d'intrigue dans un environnement moderne qui m'a permis de faire:

#!/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.

Cela s’exécute parfaitement en ligne de commande dans un environnement avec un gnuplot récent (5.0.3 dans mon cas).

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

Une fois chargé sur mon serveur et exécuté, il a échoué car la version du serveur était 4.6.4 (actuelle sur Ubuntu 14.04 LTS). La cale ci-dessous a résolu ce problème sans nécessiter de modification du script d'origine.

#!/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 combinaison de ces deux scripts permet aux paramètres d'être passés des scripts bash à gnuplot sans tenir compte de la version de gnuplot et dans pratiquement n'importe quel * nix.

11
bp.

Vous pouvez même faire de la magie Shell, par exemple comme ça:

#!/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

Mon implémentation est un peu plus complexe (par exemple, remplacer certains jetons magiques dans l'appel sed alors que j'y suis déjà ...), mais j'ai simplifié cet exemple pour une meilleure compréhension. Vous pouvez aussi simplifier encore plus les choses ... YMMV.

5
Stefan

Dans le shell écrire

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

et consécutivement les fichiers que vous voulez. -persist est utilisé pour que l'écran gnuplot reste aussi longtemps que l'utilisateur ne le quitte pas manuellement.

4
Aniruddha Bera

Voici un autre moyen:

Vous avez un script gnuplot nommé scriptname.gp:

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

plot FILENAME

Vous pouvez maintenant appeler le script gnuplot scriptname.gp par cette paix de syntaxe compliquée:

echo "call \"scriptname.gp\" \"'.'\" \"'data.dat'\"" | gnuplot 
2
con-f-use