Comment passer l'argument de ligne de commande à gnuplot?

148

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 commandes, disons foo.plt , et j'ai exécuté la commande gnuplot foo.plgpour tracer les données. Cependant, je veux passer le nom du fichier de données comme argument de commande, par exemple commande en cours d'exécution gnuplot foo.plg foo.data. Comment analyser les arguments de ligne de commande dans le fichier de script gnuplot? Merci.

Yun Huang
la source

Réponses:

191

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 -edoit précéder le nom de fichier sinon le fichier s'exécute avant les -einstructions. En particulier, exécuter un gnuplot shebang #!/usr/bin/env gnuplotavec des ./foo.plg -e ...arguments CLI ignorera l'utilisation des arguments fournis.

Jari Laamanen
la source
20
Cela peut également être utilisé avec ifpour fournir des valeurs par défaut. if ! exists("filename") filename='default.data'
mgilson
10
Pour les gens qui trébuchent maintenant, le commentaire de mgilson et le patchlevel 3 de Gnuplot 4.6 nécessitent if (!exists("filename")au lieu de if ! exists("filename").
Sam Mussmann
Comment faire la même chose sous Windows?
padawan
6
@Chong: Soit les enchaîner, soit chacun d'eux dans un -eargument, par exemple -e "filename='default.data'; foo='bar'"ou -e "filename='default.data'" -e "foo='bar"'.
Thor le
1
Remarque: l' -e ...option doit précéder le nom du fichier. En effet à partir de man gnuplotnous pouvons lire: -e"command list" exécute les commandes demandées avant de charger le fichier d'entrée suivant . .
Hastur
57

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 ARG1aux ARG9variables 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 versions antérieures, il existe un callmécanisme avec une syntaxe différente (désormais obsolète). Les arguments sont accessibles par $#, $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 comme (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, de même que $0le premier argument, et les variables sont appelées entre guillemets. Il n'y a aucun moyen de l'utiliser directement à partir de la ligne de commande, uniquement par des astuces comme celle suggérée par @ con-fu-se.

vagoberto
la source
J'ai essayé d'utiliser le -ccommutateur avec un script contenant des lignes telles que plot 'data' using 0:($1/100). gnuplotmeurt avec l'erreur expression invalide car a $1disparu. Où ai-je tort? Notez que sans -c, le script s'exécute correctement.
lorcap
Je l'ai testé avec gnuplot 5.0en ajoutant à ces exemples une ligne comme plot 'data' using 0:($1/100), et je n'ai pas compris ce que vous dites. Ce serait rare, puisque cette version définit les variables ARG0- ARG9, et non $1- $9. Je suppose que vous avez également la version 5.0 (avez-vous?), Car le -cdrapeau n'est pas pris en charge par les versions antérieures. J'aurais besoin de voir un script minimal pour voir où est le vrai problème: /
vagoberto
Je cours gnuplot 5.0 patchlevel 0sous cygwin . Le script sur une ligne print ARG1; plot 'data' using 0:($1/100)imprime correctement la valeur transmise en tant ARG1que puis se termine avec l' expression d' erreur non valide pointant sur la barre oblique de print ARG1; plot 'data' using 0:(/100).
lorcap
27

Vous pouvez également transmettre des informations via l'environnement comme suggéré ici . L'exemple d' 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
Thor
la source
6
Au lieu d'exporter, vous pouvez taper name=plot_data_file ./the_gnuplot_script.
Edgar Bonet
@Edgar Bonet: Quelle version de gnuplot est nécessaire pour cela? Cela ne semble pas fonctionner sur une machine qui utilise 4.2 ...
Bjoern
Salut @Bjoern! J'utilise Gnuplot 4.6, mais ce n'est pas une fonctionnalité de Gnuplot, c'est une fonctionnalité du shell: name=value commanddit au shell d'exécuter la commande avec cette variable particulière dans son environnement. J'utilise bash 4.3.11, mais je pense que c'est une fonctionnalité de shell très courante.
Edgar Bonet
23

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 voir, plus de paramètres sont passés avec des points-virgules (comme dans les scripts bash), mais les variables de chaîne DOIVENT être encapsulées avec '' (syntaxe gnuplot, PAS syntaxe Bash)

Mo3bius
la source
1
Pour gnuplot lui-même, peu importe si vous utilisez 'ou "pour les chaînes. Les guillemets extérieurs autour de l' -eargument doivent être "remplacés par les variables bash. Ce qui suit fonctionne également très bien:OUTPUT=foobar; gnuplot -e "output=\"$OUTPUT\"; print output"
Christoph
Merci de confirmer que je peux utiliser des points-virgules pour séparer les commandes. Aucune des autres réponses ne le montre.
tommy.carstensen
14

Vous pouvez utiliser astuce dans un environnement unix / linux:

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

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

arto
la source
12

Cette question a reçu une bonne réponse, mais je pense que je peux trouver un créneau à combler ici, ne serait-ce que pour réduire la charge de travail de quelqu'un qui cherche sur Google comme moi. 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 de tracé dans un environnement à jour 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 bien depuis la 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 télé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). Le shim 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 de passer des paramètres des scripts bash aux scripts gnuplot sans tenir compte de la version de gnuplot et dans pratiquement n'importe quel * nix.

bp.
la source
5

Vous pouvez même faire de la magie de shell, par exemple comme ceci:

#!/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 (ex: remplacement de quelques 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 également le rendre encore plus simple ... YMMV.

Stefan
la source
4

Dans le shell, écrivez

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

et consécutivement les fichiers souhaités. -persist est utilisé pour faire en sorte que l'écran de gnuplot reste tant que l'utilisateur ne le quitte pas manuellement.

Aniruddha Bera
la source
Dans la console Win7, l'option -persist ne semble pas fonctionner? Par exemple, gnuplot -persist -c "myscript.plt" "mydata.csv" "myoutput.png"cette commande fonctionne bien et j'obtiens le fichier "myoutput.png" comme je m'y attendais, mais l'écran gnuplot n'apparaît pas (AUCUNE exitcommande dans myscript.plt). Pourquoi? Et comment faire apparaître l'écran gnuplot dans mon exemple?
lyl
1

Encore une autre façon est la suivante:

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.gppar cette paix de syntaxe alambiquée:

echo "call \"scriptname.gp\" \"'.'\" \"'data.dat'\"" | gnuplot 
embrouiller
la source
0

La réponse de @ vagoberto semble la meilleure à mon humble avis si vous avez besoin d'arguments de position , et j'ai une petite amélioration à ajouter.

suggestion 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 

qui est appelé par:

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

pour ces typeurs paresseux comme moi, on pourrait rendre le script exécutable ( chmod 755 script.gp)

puis utilisez ce qui suit:

#!/usr/bin/env gnuplot -c

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

et exécutez-le comme:

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