Bagaimana cara meneruskan argumen baris perintah ke gnuplot?

148

Saya ingin menggunakan gnuplot untuk menggambar angka dari file data, katakan foo.data . Saat ini, saya hardcoded nama file data dalam file perintah, katakan foo.plt , dan jalankan perintah gnuplot foo.plguntuk memplot data. Namun, saya ingin meneruskan nama file data sebagai argumen perintah, misalnya menjalankan perintah gnuplot foo.plg foo.data. Bagaimana cara menguraikan argumen baris perintah dalam file skrip gnuplot? Terima kasih.

Yun Huang
sumber

Jawaban:

191

Anda dapat memasukkan variabel melalui sakelar -e

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

Di foo.plg Anda bisa menggunakan variabel itu

$ cat foo.plg 
plot filename
pause -1

Untuk membuat "foo.plg" sedikit lebih umum, gunakan sebuah kondisi:

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

Catatan yang -eharus mendahului nama file kalau tidak file berjalan sebelum -epernyataan. Secara khusus, menjalankan shebang gnuplot #!/usr/bin/env gnuplotdengan ./foo.plg -e ...argumen CLI akan mengabaikan penggunaan argumen yang disediakan.

Jari Laamanen
sumber
20
Ini juga dapat digunakan dengan ifuntuk memasok default. if ! exists("filename") filename='default.data'
mgilson
10
Untuk orang-orang yang tersandung di sini sekarang, komentar mgilson dan Gnuplot 4.6 patchlevel 3 diperlukan if (!exists("filename")sebagai gantinya if ! exists("filename").
Sam Mussmann
Bagaimana cara melakukan hal yang sama di windows?
padawan
6
@Chong: Baik merangkai mereka bersama atau memberikan masing-masing dalam -eargumen, misalnya -e "filename='default.data'; foo='bar'"atau -e "filename='default.data'" -e "foo='bar"'.
Thor
1
Catatan: The -e ...opsi memiliki mendahului nama file. Memang dari man gnuplotkita dapat membaca: -e"daftar perintah" mengeksekusi perintah yang diminta sebelum memuat file input berikutnya . .
Hastur
57

Anda bisa meneruskan argumen ke skrip gnuplot sejak versi 5.0, dengan benderanya -c. Argumen ini diakses melalui variabel ARG0ke ARG9, ARG0menjadi skrip, dan ARG1ke ARG9variabel string. Jumlah argumen diberikan oleh ARGC.

Misalnya, skrip berikut ("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 

dapat disebut sebagai:

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

atau di dalam gnuplot sebagai

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

Di gnuplot 4.6.6 dan sebelumnya, ada callmekanisme dengan sintaks yang berbeda (sekarang sudah usang). Argumen diakses melalui $#, $0, ..., $9. Misalnya, skrip yang sama di atas terlihat seperti:

#!/usr/bin/gnuplot --persist

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

dan itu disebut di dalam gnuplot sebagai (ingat, versi <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

Perhatikan bahwa tidak ada variabel untuk nama skrip, begitu $0juga argumen pertama, dan variabel-variabel tersebut disebut dalam tanda kutip. Tidak ada cara untuk menggunakan ini langsung dari baris perintah, hanya melalui trik seperti yang disarankan oleh @ con-fu-se.

vagoberto
sumber
Saya mencoba menggunakan -csakelar dengan skrip yang berisi baris seperti plot 'data' using 0:($1/100). gnuplotmati dengan ekspresi kesalahan tidak valid karena $1dihilangkan. Dimana saya salah Perhatikan bahwa tanpa -c, skrip berjalan dengan sukses.
lorcap
Saya mengujinya dengan gnuplot 5.0menambahkan contoh-contoh ini seperti garis plot 'data' using 0:($1/100), dan tidak mengerti apa yang Anda katakan. Ini akan menjadi langka, karena versi ini mendefinisikan variabel ARG0- ARG9, dan bukan $1- $9. Saya berasumsi Anda juga memiliki versi 5.0 (apakah Anda?), Karena -cbendera tidak didukung oleh versi sebelumnya. Saya perlu melihat skrip minimal untuk melihat di mana masalah sebenarnya: /
vagoberto
Saya berlari di gnuplot 5.0 patchlevel 0bawah cygwin . Skrip satu baris print ARG1; plot 'data' using 0:($1/100)dengan benar mencetak nilai yang diteruskan sebagai ARG1dan kemudian keluar dengan kesalahan ekspresi tidak valid yang menunjuk pada garis miring print ARG1; plot 'data' using 0:(/100).
lorcap
27

Anda juga dapat meneruskan informasi melalui lingkungan seperti yang disarankan di sini . Contoh oleh Ismail Amin diulangi di sini:

Di shell:

export name=plot_data_file

Dalam skrip Gnuplot:

#! /usr/bin/gnuplot

name=system("echo $name")
set title name
plot name using ($16 * 8):20 with linespoints notitle
pause -1
Thor
sumber
6
Alih-alih ekspor, Anda dapat mengetik name=plot_data_file ./the_gnuplot_script.
Edgar Bonet
@ Edgar Bonet: Versi gnuplot mana yang diperlukan untuk ini? Tampaknya tidak berhasil pada mesin y yang menggunakan 4.2 ...
Bjoern
Hai @Bern! Saya menggunakan Gnuplot 4.6, tetapi ini bukan fitur Gnuplot, ini fitur dari shell: name=value commandmemberi tahu shell untuk menjalankan perintah dengan variabel tertentu di lingkungannya. Saya menggunakan bash 4.3.11, tapi saya percaya ini adalah fitur shell yang sangat umum.
Edgar Bonet
23

Jawaban Jari Laamanen adalah solusi terbaik. Saya hanya ingin menjelaskan cara menggunakan lebih dari 1 parameter input dengan variabel shell:

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

dan foo.plg:

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

Seperti yang Anda lihat, lebih banyak parameter dilewatkan dengan titik koma (seperti dalam skrip bash), tetapi variabel string PERLU untuk dienkapsulasi dengan '' (sintaks gnuplot, BUKAN sintaks Bash)

Mo3bius
sumber
1
Untuk gnuplot itu sendiri, tidak masalah jika Anda menggunakan 'atau "untuk string. Kutipan luar di sekitar -eargumen harus "memiliki variabel bash diganti. Yang berikut ini juga berfungsi dengan baik:OUTPUT=foobar; gnuplot -e "output=\"$OUTPUT\"; print output"
Christoph
Terima kasih telah mengonfirmasi bahwa saya dapat menggunakan titik koma untuk membagi perintah. Tidak ada jawaban lain yang menunjukkan ini.
tommy.carstensen
14

Anda dapat menggunakan trik di lingkungan unix / linux:

  1. dalam program gnuplot: plot "/ dev / stdin" ...

  2. Pada baris perintah: gnuplot program.plot <data.dat

arto
sumber
12

Pertanyaan ini dijawab dengan baik tetapi saya pikir saya dapat menemukan ceruk untuk diisi di sini terlepas, jika hanya untuk mengurangi beban kerja pada seseorang yang melakukan googling seperti ini. Jawaban dari vagoberto memberi saya apa yang saya butuhkan untuk menyelesaikan versi masalah ini dan saya akan membagikan solusi saya di sini.

Saya mengembangkan skrip plot di lingkungan terbaru yang memungkinkan saya untuk melakukan:

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

Ini dijalankan dengan sangat baik dari command-line di lingkungan dengan gnuplot baru-baru ini (5.0.3 dalam kasus saya).

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

Ketika diunggah ke server saya dan dieksekusi, gagal karena versi server 4.6.4 (saat ini di Ubuntu 14.04 LTS). Shim di bawah ini menyelesaikan masalah ini tanpa memerlukan perubahan apa pun pada skrip asli.

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

Kombinasi kedua skrip ini memungkinkan parameter untuk diteruskan dari skrip bash ke gnuplot tanpa memperhatikan versi gnuplot dan pada dasarnya setiap * nix.

bp.
sumber
5

Anda bahkan dapat melakukan beberapa shell magic, misalnya seperti ini:

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

Implementasi saya sedikit lebih kompleks (misalnya mengganti beberapa token ajaib dalam panggilan sed, sementara saya sudah melakukannya ...), tapi saya menyederhanakan contoh ini untuk pemahaman yang lebih baik. Anda juga bisa membuatnya lebih sederhana .... YMMV.

Stefan
sumber
4

Di shell menulis

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

dan secara berurutan file yang Anda inginkan. -persist digunakan untuk membuat layar gnuplot tetap selama pengguna tidak keluar secara manual.

Aniruddha Bera
sumber
Di konsol Win7, opsi -persist tampaknya tidak berfungsi? Sebagai contoh, gnuplot -persist -c "myscript.plt" "mydata.csv" "myoutput.png"perintah ini berfungsi dengan baik dan saya mendapatkan file "myoutput.png" seperti yang saya harapkan, tetapi layar gnuplot tidak muncul (TIDAK ada exitperintah di myscript.plt). Mengapa? Dan bagaimana cara membuat layar gnuplot tampil dalam contoh saya?
lyl
1

Namun cara lain adalah ini:

Anda memiliki skrip gnuplot bernama scriptname.gp:

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

plot FILENAME

Sekarang Anda dapat memanggil skrip gnuplot scriptname.gpdengan ketenangan sintaks yang berbelit-belit:

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

@ vagoberto's jawaban tampaknya IMHO terbaik jika Anda memerlukan argumen posisi , dan saya punya sedikit peningkatan untuk ditambahkan.

Saran 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 

yang dipanggil oleh:

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

untuk pengetik malas seperti saya, orang dapat membuat skrip dapat dieksekusi ( chmod 755 script.gp)

kemudian gunakan yang berikut ini:

#!/usr/bin/env gnuplot -c

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

dan jalankan sebagai:

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