Come passare l'argomento della riga di comando a gnuplot?


148

Voglio usare gnuplot per disegnare figure dal file di dati, diciamo foo.data . Attualmente, ho codificato il nome del file di dati nel file di comando, ad esempio foo.plt , ed eseguo il comando gnuplot foo.plgper tracciare i dati. Tuttavia, desidero passare il nome del file di dati come argomento di comando, ad esempio comando in esecuzione gnuplot foo.plg foo.data. Come analizzare gli argomenti della riga di comando nel file di script gnuplot? Grazie.

Risposte:


191

È possibile inserire variabili tramite switch -e

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

In foo.plg puoi quindi usare quella variabile

$ cat foo.plg 
plot filename
pause -1

Per rendere "foo.plg" un po 'più generico, usa un condizionale:

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

Si noti che -edeve precedere il nome file, altrimenti il ​​file viene eseguito prima delle -eistruzioni. In particolare, l'esecuzione di uno shebang gnuplot #!/usr/bin/env gnuplotcon ./foo.plg -e ...argomenti CLI ignorerà l'utilizzo degli argomenti forniti.


20
Questo può anche essere usato con ifper fornire valori predefiniti. if ! exists("filename") filename='default.data'
mgilson,

10
Per le persone che si imbattono ora in questo, il commento di mgilson e Gnuplot 4.6 patchlevel 3 richiedono if (!exists("filename")invece di if ! exists("filename").
Sam Mussmann,

Come fare la stessa cosa in Windows?
Padawan,

6
@Chong: O li stringi insieme o ciascuno di essi in un -eargomento, ad esempio -e "filename='default.data'; foo='bar'"o -e "filename='default.data'" -e "foo='bar"'.
Thor,

1
Nota: l' -e ...opzione deve precedere il nome file. Infatti da man gnuplotnoi possiamo leggere: -e"elenco comandi" esegue i comandi richiesti prima di caricare il file di input successivo . .
Hastur,

57

Puoi passare argomenti a uno script gnuplot dalla versione 5.0, con il flag -c. Questi argomenti sono accessibili attraverso le variabili ARG0a ARG9, ARG0essendo lo script, e ARG1per ARG9le variabili stringa. Il numero di argomenti è dato da ARGC.

Ad esempio, il seguente 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 

può essere chiamato come:

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

o all'interno di gnuplot come

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

In gnuplot 4.6.6 e precedenti, esiste un callmeccanismo con una sintassi diversa (ora deprecata). Gli argomenti sono accessibili attraverso $#, $0, ..., $9. Ad esempio, lo stesso script sopra appare come:

#!/usr/bin/gnuplot --persist

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

e viene chiamato in gnuplot come (ricorda, versione <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

Si noti che non esiste alcuna variabile per il nome dello script, quindi $0è il primo argomento e le variabili vengono chiamate tra virgolette. Non c'è modo di usarlo direttamente dalla riga di comando, solo attraverso i trucchi come quello suggerito da @ con-fu-se.


Ho provato a utilizzare l' -copzione con uno script che contiene righe come plot 'data' using 0:($1/100). gnuplotmuore con l' espressione di errore non valida perché $1è scomparsa. Dove sbaglio? Si noti che senza -c, lo script viene eseguito correttamente.
Lorcap

L'ho provato gnuplot 5.0aggiungendo a questi esempi una riga simile plot 'data' using 0:($1/100)e non ho ottenuto quello che dici. Sarebbe raro, poiché questa versione definisce le variabili ARG0- ARG9e non $1- $9. Presumo che tu abbia anche la versione 5.0 (vero?), Poiché il -cflag non è supportato dalle versioni precedenti. Avrei bisogno di vedere uno script minimo per vedere dov'è il vero problema: /
vagoberto

Sto correndo gnuplot 5.0 patchlevel 0sotto Cygwin . Lo script di una riga print ARG1; plot 'data' using 0:($1/100)stampa correttamente il valore passato come ARG1e quindi esce con l' espressione di errore non valida che punta alla barra di print ARG1; plot 'data' using 0:(/100).
Lorcap

27

È inoltre possibile trasmettere informazioni attraverso l'ambiente come suggerito qui . L'esempio di Ismail Amin è ripetuto qui:

Nella shell:

export name=plot_data_file

In uno script Gnuplot:

#! /usr/bin/gnuplot

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

6
Invece di esportare, puoi digitare name=plot_data_file ./the_gnuplot_script.
Edgar Bonet,

@Edgar Bonet: quale versione di gnuplot è richiesta per questo? Non sembra funzionare su una macchina che utilizza 4.2 ...
Bjoern

Ciao @Bjoern! Sto usando Gnuplot 4.6, ma questa non è una funzionalità Gnuplot, è una caratteristica della shell: name=value commanddice alla shell di eseguire il comando con quella particolare variabile nel suo ambiente. Sto usando bash 4.3.11, ma credo che sia una funzionalità shell molto comune.
Edgar Bonet,

23

La risposta di Jari Laamanen è la soluzione migliore. Voglio solo spiegare come utilizzare più di 1 parametro di input con variabili shell:

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

e foo.plg:

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

Come puoi vedere, più parametri vengono passati con punti e virgola (come negli script bash), ma le variabili stringa DEVONO essere incapsulate con '' (sintassi gnuplot, sintassi NOT Bash)


1
Per gnuplot stesso non importa se usi 'o "per stringhe. Le virgolette esterne attorno -eall'argomento devono essere "per sostituire le variabili bash. Funziona anche bene:OUTPUT=foobar; gnuplot -e "output=\"$OUTPUT\"; print output"
Christoph,

Grazie per aver confermato che posso usare i punti e virgola per dividere i comandi. Nessuna delle altre risposte lo mostra.
tommy.carstensen,

14

Puoi usare il trucco in ambiente unix / linux:

  1. nel programma gnuplot: trama "/ dev / stdin" ...

  2. Nella riga di comando: gnuplot program.plot <data.dat


12

Questa domanda ha una buona risposta, ma penso di poter trovare una nicchia da riempire qui indipendentemente, se non altro per ridurre il carico di lavoro su qualcuno che cerca su Google come ho fatto io. La risposta di vagoberto mi ha dato ciò di cui avevo bisogno per risolvere la mia versione di questo problema e quindi condividerò la mia soluzione qui.

Ho sviluppato uno script di trama in un ambiente aggiornato che mi ha permesso di fare:

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

Questo funziona perfettamente dalla riga di comando in un ambiente con un recente gnuplot (5.0.3 nel mio caso).

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

Quando è stato caricato sul mio server ed eseguito, non è riuscito perché la versione del server era 4.6.4 (corrente su Ubuntu 14.04 LTS). Lo spessore sotto ha risolto questo problema senza richiedere alcuna modifica allo script originale.

#!/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 combinazione di questi due script consente di passare i parametri dagli script bash a gnuplot indipendentemente dalla versione di gnuplot e praticamente in qualsiasi * nix.


5

Potresti anche fare un po 'di magia conchiglia, ad esempio in questo modo:

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

La mia implementazione è un po 'più complessa (ad esempio sostituendo alcuni token magici nella chiamata sed, mentre ci sono già ...), ma ho semplificato questo esempio per una migliore comprensione. Potresti anche renderlo ancora più semplice .... YMMV.


4

Nella shell scrivi

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

e consecutivamente i file desiderati. -persist è usato per far rimanere lo schermo di gnuplot fintanto che l'utente non lo esce manualmente.


Nella console Win7, l'opzione -persist sembra non funzionare? Ad esempio, gnuplot -persist -c "myscript.plt" "mydata.csv" "myoutput.png"questo comando funziona bene e ottengo il file "myoutput.png" come mi aspetto, ma la schermata di gnuplot non viene visualizzata (NESSUN exitcomando in myscript.plt). Perché? E come rendere lo schermo di gnuplot nel mio esempio?
lyl

1

Ancora un altro modo è questo:

Hai uno script gnuplot chiamato scriptname.gp:

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

plot FILENAME

Ora puoi chiamare lo script gnuplot scriptname.gpcon questa contorta tranquillità di sintassi:

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

0

La risposta di @vagoberto sembra il migliore IMHO se hai bisogno di argomenti posizionali , e ho un piccolo miglioramento da aggiungere.

Il suggerimento di 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 

che viene chiamato da:

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

per quei battitori pigri come me, uno potrebbe rendere eseguibile lo script ( chmod 755 script.gp)

quindi utilizzare quanto segue:

#!/usr/bin/env gnuplot -c

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

ed eseguirlo come:

$ ./imb.plot a b c d
script name        : ./imb.plot
first argument     : a
third argument     : c
number of arguments: 4
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.