2011-09-24 11 views
9

私はもともとこれがgnuplot - start of X series - Stack Overflowと同じであると思っていましたが、これは少し具体的だと思います。データセット値をgnuplot変数に読み込む(Xシリーズの開始)

私は「Xシリーズの始まり」を見つけることに興味があるので、話すために - 例を明確にしようと思います。このスクリプトを持っていると言う:

# generate data 
system "cat > ./inline.dat <<EOF\n\ 
10.0 1 a 2\n\ 
10.2 2 b 2\n\ 
10.4 3 a 2\n\ 
10.6 4 b 2\n\ 
10.8 5 c 7\n\ 
11.0 5 c 7\n\ 
EOF\n" 

# ranges 
set yrange [0:8] 
set xrange [0:11.5] 

plot "inline.dat" using 1:2 with impulses linewidth 2 

あなたはそれをプロットした場合、あなたはデータをx軸上の10から始まりわかります:

gnuplot-startx.png

さて、もちろん、あなたがxrangeを調整することができます - しかし時々、あなたは "0から"始まる "相対的な位置"に興味があるので、話す。そのため、一つは、我々は、データが10.0から始まる知っているので、それは0から始まりますので、我々は明示的に最初の列からそれを引くことができ、x軸上で「左に移動」のデータを参照したいと思います:

plot "inline.dat" using ($1-10.0):2 with impulses linewidth 2 

...それは基本的にトリックです。

しかし、を入力しないでください上記のplotコマンドで明示的に "10.0"を指定したい場合は、既にロードされているデータの最初の列の最初の要素であることを知っていれば、この値を何らかの形で変数に読み込む方法があるといいでしょう。たとえば、次のような疑似コードを使用します。

varval = "inline.dat"(1,1) # get first element of first column in variable 
plot "inline.dat" using ($1-varval):2 with impulses linewidth 2 

...このようなものでは、plotコマンドで手動でこの "x offset"値を指定する必要はありません。

言い換えれば、xシリーズ(データセット内の指定された列の最初の値)の先頭を変数としてに読み込む方法はありますか?

答えて

6

二つの方法:

1. プロット機能を最初にしてみましょう息子

plot "inline.dat" using 1:2 with impulses linewidth 2 

xmin = GPVAL_DATA_X_MIN 
plot "inline.dat" using ($1-xmin):2 with impulses linewidth 2 

2. 最小のx値であるかを把握するには、外部スクリプトを使用する:最小x値を伝えるためにたくさん

xmin = `sort -nk 1 inline.dat | head -n 1 | awk '{print $1}'` 
plot "inline.dat" using ($1-xmin):2 with impulses linewidth 2 
+0

大変 - 簡潔な回答をいただき、ありがとうございました。 – sdaau

+0

はい、ただし、必ずしも最小限にする必要はないデータ系列の*最初の要素に興味があればどうしますか? – TMOTTM

+0

@TMOTTMの場合、最初の要素だけを使用するように外部スクリプトを調整する必要があります(awkをソート部分なしで直接使用する)。 – EverythingRightPlace

2

うーん... OK、私は何かを得た:機能initerをスキャンするために使用されているよう

initer(x) = (!exists("first")) ? first = x : first ; 
plot "inline.dat" using ($1-initer($1)):2 with impulses linewidth 2 

を...しかし、これはそれを読んでよりも、より多くの変数を「キャプチャ」のように見えます数字の流れは、最初のものを検出し、その値を返す):)これを行うには良い方法がある願っています....

3

OK、私はこれに帰ってくる - 私は考えます

ここで、gnuplotとすれば、データプロットは2Dプロットとしてプロットされます。これは、何らかの形で2D構造や配列を扱っていることを前提としています。だから誰かがC、Perl、Pythonなどから来ている理由です何らかの形でデータセットのインデックスを作成し、与えられた行と列の位置で値を取得できることは当然考えられます。 、次の擬似コードのようなものを言う:

my_val = "inline.dat"[1][2]  # get value in 1st row and 2nd column 

または交互に、擬似コード:
my_dataset = parse_dataset("inline.dat")
my_val = get_value(my_dataset, 1, 2)

そして私はgnuplotでこのような何かを探している時間のトンを過ごした、とすることはできませんそのようなものを見つけます(行と列のインデックスによるデータセット値への直接的な変数アクセス)。 しかできないようですが、plotのデータセットです。おそらく値はusingという部分で呼び出された関数を介してアクセスしているようです。種類の私は適切なplot声明:)を構築するために、正確にこれらの値を必要とする場合でも、そして私 - 私はgnuplotからいくつかのデータセットの値を検索する場合、私はplotを呼び出すことにより、データセットを反復処理するを持っていることを、意味

私ができる少なくともので - 最初plotは何とかもstdoutまたは/dev/null、ファイルへのアウトfinding maximum value in a data set and subtracting from plot - comp.graphics.apps.gnuplot | Google Groupsポイント、1 できplotとして、しかし:)その後秒を台無しにし、プレーンなASCII形式のテーブルを取得することを考え、ことを嫌いますその方法で最初の通話をリダイレクトするので、行動に干渉しません2番目の呼び出しのターミナルをplotにプロットします。

そこで、以下「inline.dat」データセットの最初の列の最初の要素を介して取得された他のコード例は、次のとおりですので、次にプロットは直接にfirstによって相殺することができる

# print and get (in _drcv) first value of first data column: 
eval print_dataset_row_column("inline.dat",0,1) 

# must "copy" the "return" value manually: 
first = _drcv 

... plotコール。

注意が再びprint_dataset_row_column呼び出しplotは(set table/dev/nullに経由してリダイレクト)することを - そのように、あなたはそれを呼び出す時間が単一値を取得するには、それは全体データセットによる反復処理が発生します!だから、最初の要素と最後の要素(そしておそらくsome basic statistics with gnuplotのような他の要素)が必要な場合は、print_dataset_row_columnを書き直して、一度にすべての要素を取得する方が良いでしょう。

また、データセットに特殊なフォーマットを使用し、using行を書き換える場合は、print_dataset_row_column書き換えが必要です。この例では、3番目の列は文字列です。デフォルトではプロットデータ列として受け入れられません。そのため、print_dataset_*関数の呼び出しは処理する必要があります(gnuplot plot from stringも参照してください)。このスクリプトが呼び出されると

# generate data 
system "cat > ./inline.dat <<EOF\n\ 
10.0 1 a 2\n\ 
10.2 2 b 2\n\ 
10.4 3 a 2\n\ 
10.6 4 b 2\n\ 
10.8 5 c 7\n\ 
11.0 5 c 7\n\ 
EOF\n" 

### "dry-run" functions: 
# iterate through dataset by calling 
# `plot`, redirected to file output (via `set table`) 
# 
# note: eval (not print) cannot be inside a user-defined function: 
# a(b) = eval('c=3') ; print a(4) ==> "undefined function: eval" 
# nor you can make multistatement functions with semicolon: 
# f(x) = (2*x ; x=x+2) ==> ')' expected (at ';') 
# 
# so these functions are defined as strings - and called through eval 
# 
# through a single column spec in `using`: 
# (`plot` prints table to stdout) 
# 
print_dataset_column(filename,col) = "set table '/dev/stdout' ;\ 
plot '".filename."' using ".col." ;\ 
unset table" 
# 
# through two column spec in `using`: 
# (`plot` prints table to stdout) 
# 
print_dataset_twocolumn(filename,colA,colB) = "set table '/dev/stdout' ;\ 
plot '".filename."' using ".colA.":".colB." ;\ 
unset table" 
# 
# print value of row:column in dataset, saving it as _drcv variable 
# 
# init variable 
# 
_drcv = 0 
# 
# create _drc helper function; note assign and "return" in 
# true branch of ternary clause 
# 
_drc(ri, colval, col) = (ri == _row) ? _drcv = colval : colval 
# 
# define the callable function: 
# 
print_dataset_row_column(filename,row,col) = "_row = ".row." ;\ 
set table '/dev/null' ;\ 
plot '".filename."' using (_drc($0, $".col.", ".col.")) ;\ 
unset table ;\ 
print '".filename."[r:".row.",c:".col."] = ',_drcv" 
# 
# 
### end dry run functions 


# 
# test print_dataset_* functions: 
# 

eval print_dataset_column("inline.dat",0) 
eval print_dataset_twocolumn("inline.dat",0,0) 

# string column - cannot directly: 
# set table '/dev/stdout' ;plot 'inline.dat' using 3 ;unset table 
#            ^
# line 69: warning: Skipping data file with no valid points 
# line 69: x range is invalid 
#~ eval print_dataset_column("inline.dat",3) 

eval print_dataset_column("inline.dat",1) 
eval print_dataset_twocolumn("inline.dat",1,2) 

eval print_dataset_row_column("inline.dat",4,1) 
eval print_dataset_row_column("inline.dat",4,2) 

# will fail - 3 is string column 
# line 82: warning: Skipping data file with no valid points 
# line 82: x range is invalid 
#~ eval print_dataset_row_column("inline.dat",4,3) 


# 
# do a plot offset by first element position 
# 

# print and get (in _drcv) first value of first data column: 
eval print_dataset_row_column("inline.dat",0,1) 
# must "copy" the "return" value manually: 
first = _drcv 

# ranges 
set yrange [0:8] 
set xrange [0:11.5] 

# plot finally: 
plot "inline.dat" using ($1-first):2 with impulses linewidth 2 

、OPでのデータセットは0から始まる、移動プロットされて - と、次のはtest.gpそれを呼びましょう - だからここ

 

は、サンプルコードです

gnuplot> load './test.gp' 

# Curve 0 of 1, 6 points 
# Curve title: "'inline.dat' using 0" 
# x y type 
0 0 i 
1 1 i 
2 2 i 
3 3 i 
4 4 i 
5 5 i 


# Curve 0 of 1, 6 points 
# Curve title: "'inline.dat' using 0:0" 
# x y type 
0 0 i 
1 1 i 
2 2 i 
3 3 i 
4 4 i 
5 5 i 


# Curve 0 of 1, 6 points 
# Curve title: "'inline.dat' using 1" 
# x y type 
0 10 i 
1 10.2 i 
2 10.4 i 
3 10.6 i 
4 10.8 i 
5 11 i 


# Curve 0 of 1, 6 points 
# Curve title: "'inline.dat' using 1:2" 
# x y type 
10 1 i 
10.2 2 i 
10.4 3 i 
10.6 4 i 
10.8 5 i 
11 5 i 

inline.dat[r:4,c:1] = 10.8 
inline.dat[r:4,c:2] = 5.0 
inline.dat[r:0,c:1] = 10.0 
:端子に出力(最初のいくつかのテーブル印刷物はstdoutset tableplot介してリダイレクトからの実際の出力されます)
3

は、データファイルから単一の値を読み取るために検討し、次のユーザー定義関数:

もちろん
at(file, row, col) = system(sprintf("awk -v row=%d -v col=%d 'NR == row {print $col}' %s", row, col, file)) 
file="delta-fps" ; row=2 ; col=2 
print at(file,row,col) 

、AWKへの入力は無視/無効な入力(空白行、コメントなど)のクリアする必要があります。例:

at(file, row, col) = system(sprintf("grep -v '^#|^$' %s | awk -v row=%d -v col=%d 'NR == row {print $col}'", file, row, col)) 

なお、この機能はデータセットの読み取りを許可しません。ファイルには制限があります。

at(file, row, col)=system(sprintf("%s | grep -v '^#\\|^$' | awk -v row=%d -v col=%d 'NR == row {print $col}'", (file[:1] eq '<') ? file[2:] :'cat '.file, row, col)) 

良い点は、そのような慰めを定義するには:しかし、この制限は、ファイル名の引数にリダイレクト文字「<」をチェックし、(三項演算子を参照)賢明な方法でそれを置き換えることによって克服することができますあなたの.gnuplot initファイルかもしれません。

+0

それをありがとう、@Hannes - 覚えておくと便利なアプローチ。乾杯! – sdaau

関連する問題