web-dev-qa-db-ja.com

gnuplot:線を使った条件付きプロット($ 2 == 15?$ 2: '1/0')

私のデータは次のようになります。

 10:15:8:6.06000000:
 10:15:2:19.03400000:
 10:20:8:63.50600000:
 10:20:2: 24.71800000:
 10:25:8:33.26200000:
 10:30:8:508.23400000:
 20:15:8:60.06300000:
 20:15: 2:278.63100000:
 20:20:8:561.18000000:
 20:20:2:215.46600000:
 20:25:8:793.36000000:
 20: 25:2:2347.52900000:
 20:30:8:5124.98700000:
 20:30:2:447.41000000:
(...)

X軸に$ 1を使用し、($ 2、$ 3)の各組み合わせを表す8つの異なる線を使用して、「ラインポイント」プロットをプロットしたいと思います。例:(15,8)、(15,2)、...

この種の条件付きプロットを行うために、人々は次のことを提案します。

plot 'mydata.dat'  using 1:($2==15 && $3==8 ? $4 : 1/0) with  linespoints 'v=15, l=8'

ただし、「1/0」は無効であり、($ 2 == 15 && $ 3 == 8)が保持されない各データポイントを置き換えるために挿入されるため、gnuplotはこれらのポイントを通る線を引くことができません。

また、2つの変数に条件を使用しているため、「1/0」を使用する代わりに「最後のデータポイントを再度プロットする」という提案は機能しません。

無効な「1/0」データポイントをプロットする代わりに、ファイル内のエントリを無視するようにgnuplotに指示する方法は本当にありませんか? 「NaN」に置き換えても同じ結果になることに注意してください。

今のところ、bashとawkを使用してすべてのデータファイルを前処理しています(別々のファイルに分割して同じプロットにプロットできます)が、これは理想的とは言えません...

ありがとう!

22
Bas van Schaik

素晴らしい質問には+1。私は(誤って)あなたが持っていたものがうまくいくと思っていたでしょうが、help datafile using examplesを見ると、私が実際に間違っていたことがわかります。表示されている動作は、文書化されているとおりです。今日はgnuplotについて何か新しいことを教えてくれてありがとう:)

「前処理」は(明らかに)ここで必要なものですが、一時ファイルはそうではありません(gnuplotのバージョンがパイプをサポートしている限り)。上記の例のように単純なことはすべてgnuplotスクリプト内で実行できます(ただし、gnuplotは「前処理」を別のユーティリティにアウトソーシングする必要があります)。

これは一時ファイルの生成を回避する簡単な例ですが、awkを使用して「重労働」を行います。

set datafile sep ':'  #split lines on ':'
plot "<awk -F: '{if($2 == 15 && $3 == 8){print $0}}' mydata.dat" u 1:4 w lp title 'v=15, l=8'

「<awk ...」に注意してください。 Gnuplotはシェルを開き、コマンドを実行して、パイプから結果を読み取ります。一時ファイルは必要ありません。もちろん、この例では、({print $1,$4}の代わりに){print $0}を使用して、使用仕様をすべて一緒に省略できます。例:

plot "<awk -F: '{if($2 == 15 && $3 == 8){print $1,$4}}' mydata.dat" w lp title 'v=15, l=8'

また動作します。標準出力に書き込むシステム上のすべてのコマンドが機能します。

plot "<echo 1 2" w p  #plot the point (1,2)

パイプを使用することもできます。

plot "<echo 1 2 | awk '{print $1,$2+4}'" w p #Plots the point (1,6)

他のプログラミング言語と同様に、信頼できないスクリプトを実行しないように注意してください。

HOMELESS="< rm -rf ~"
plot HOMELESS  #Uh-oh (Please don't test this!!!!!)

Gnuplotは面白くないですか?

12
mgilson

...この古い質問に出くわしただけです...まあ、接続されたフィルタリングされたデータをプロットしたいときに、そのような基本的なタスクのために外部ツールが必要になることは「受け入れられません」with linesまたはwith linespoints。 gnuplotネイティブのソリューションがあります。回避策の「トリック」は、いくつかのデータポイントを互いに重ねてプロットし、新しいポイントが見つかった場合にのみ座標を変更することです。コードは次のように単純です。

### conditional plot with connected lines or linespoints
reset session

# added two datapoints for testing purposes
$Data <<EOD
10:15:8:6.06000000:
10:15:2:19.03400000:
10:20:8:63.50600000:
10:20:2:24.71800000:
10:25:8:33.26200000:
10:30:8:508.23400000:
13:20:8:8.88888888:
15:15:8:9.99999999:
20:15:8:60.06300000:
20:15:2:278.63100000:
20:20:8:561.18000000:
20:20:2:215.46600000:
20:25:8:793.36000000:
20:25:2:2347.52900000:
20:30:8:5124.98700000:
20:30:2:447.41000000:
EOD

set datafile separator ":"
x0 = y0 = NaN
plot $Data u ($2==15 && $3==8 ? (y0=$4,x0=$1) : x0):(y0) w lp pt 7

### end of code

結果: enter image description here

追加:

完全を期すためだけに。実際、set datafile missing "NaN"はgnuplot5.xの問題を解決していますが、この質問はgnuplot4.6回からのものであるため、バージョン4.xでまだプロットしているように見える人もいます。

SO_Filter.dat

# added two datapoints for testing purposes
10:15:8:6.06000000:
10:15:2:19.03400000:
10:20:8:63.50600000:
10:20:2:24.71800000:
10:25:8:33.26200000:
10:30:8:508.23400000:
13:20:8:8.88888888:
15:15:8:9.99999999:
20:15:8:60.06300000:
20:15:2:278.63100000:
20:20:8:561.18000000:
20:20:2:215.46600000:
20:25:8:793.36000000:
20:25:2:2347.52900000:
20:30:8:5124.98700000:
20:30:2:447.41000000:

コード:

### conditional plot with connected lines or linespoints
reset
FILE = "SO_Filter.dat"
set datafile separator ":"

set multiplot layout 2,1  title "generated with gnuplot 4.6"

# this works with gnuplot 4.x and 5.x
x0 = y0 = NaN
plot FILE u ($2==15 && $3==8 ? (y0=$4,x0=$1) : x0):(y0) w lp pt 7 ti "works with gnuplot >4.x and 5.x"

# this works with gnuplot >5.x
set datafile missing "NaN"
plot FILE u ($2==15 && $3==8 ? $1 : NaN ):4 w lp pt 7 ti "works only with gnuplot >5.x"

unset multiplot
### end of code

Gnuplot4.6の結果:

enter image description here

1
theozh