私の.datファイルに既に適切にビニングされたデータがある場合、gnuplotでヒストグラムを作成する方法を知っています(「ボックス付き」を使用するだけです)。数値のリストを取り、gnuplotがユーザーが提供する範囲とビンサイズに基づいてヒストグラムを提供する方法はありますか?
私の.datファイルに既に適切にビニングされたデータがある場合、gnuplotでヒストグラムを作成する方法を知っています(「ボックス付き」を使用するだけです)。数値のリストを取り、gnuplotがユーザーが提供する範囲とビンサイズに基づいてヒストグラムを提供する方法はありますか?
回答:
はい、それは非常に隠されていますが、素早く簡単です:
binwidth=5
bin(x,width)=width*floor(x/width)
plot 'datafile' using (bin($1,binwidth)):(1.0) smooth freq with boxes
help smooth freq
上記がヒストグラムを作成する理由を確認してください
範囲を処理するには、xrange変数を設定します。
set boxwidth binwidth
上記に追加します。本当に助かりました。
Born2Smileの非常に便利な回答にいくつかの修正/追加があります。
set boxwidth binwidth
bin
関数を変更することで修正できます:bin(x,width)=width*floor(x/width) + width/2.0
bin(x,width)=width*floor(x/width) + binwidth/2.0
(浮動小数点の計算)
bin(x,width)=width*floor(x/width) + width/2.0
。width
引数として渡す場合は、それを使用します。:-)
非常に注意してください。このページのすべての回答は、ビニングの開始場所(必要に応じて、左端のビンの左端)をユーザーの手から暗黙的に決定しています。ユーザーがデータをビニングするためのこれらの機能のいずれかと、ビニングの開始場所に関する自分の決定を組み合わせている場合(上記にリンクされているブログで行われているように)、上記の機能はすべて正しくありません。「Min」をビニングするための任意の開始点で、正しい関数は次のとおりです。
bin(x) = width*(floor((x-Min)/width)+0.5) + Min
これが連続して正しい理由がわかります(いくつかのビンとそれらの1つのどこかに点を描くと役立ちます)。データポイントからMinを減算して、ビニング範囲内の距離を確認します。次に、ビンの幅で除算して、「ビン」の単位で効果的に作業できるようにします。次に、結果を「フロア」してそのビンの左端に移動し、0.5を追加してビンの中央に移動し、幅を乗算して、ビンの単位ではなく絶対スケールで作業するようにします。もう一度、最後に、開始時に差し引いた最小オフセットを追加します。
この関数の動作を考えてみましょう:
Min = 0.25 # where binning starts
Max = 2.25 # where binning ends
n = 2 # the number of bins
width = (Max-Min)/n # binwidth; evaluates to 1.0
bin(x) = width*(floor((x-Min)/width)+0.5) + Min
たとえば、値1.1は本当に左側のビンに該当します。
Born2Smileの答えは、ビンの境界が(n + 0.5)* binwidth(nは整数で実行される)で発生する場合にのみ正しいです。mas90の答えは、ビンの境界がn * binwidthで発生する場合にのみ正しいです。
このようなグラフをプロットしますか? はい?その後、私のブログ記事を見ることができます:http : //gnuplot-surprising.blogspot.com/2011/09/statistic-analysis-and-histogram.html
コードの重要な行:
n=100 #number of intervals
max=3. #max value
min=-3. #min value
width=(max-min)/n #interval width
#function used to map a value to the intervals
hist(x,width)=width*floor(x/width)+width/2.0
set boxwidth width*0.9
set style fill solid 0.5 # fill style
#count and plot
plot "data.dat" u (hist($1,width)):(1.0) smooth freq w boxes lc rgb"green" notitle
いつものように、Gnuplotは見栄えの良いグラフをプロットするための素晴らしいツールであり、あらゆる種類の計算を実行することができます。 ただし、これは計算機として機能するのではなくデータをプロットすることを目的としており、外部プログラム(Octaveなど)を使用してより「複雑な」計算を実行し、このデータをファイルに保存してから、Gnuplotを使用して生成する方が簡単ですグラフ。上記の問題については、「hist」関数がを使用してOctaveであることを確認し、[freq,bins]=hist(data)
これを使用してGnuplotでこれをプロットします。
set style histogram rowstacked gap 0
set style fill solid 0.5 border lt -1
plot "./data.dat" smooth freq with boxes
このディスカッションは非常に役に立ちましたが、「丸め」の問題が発生しました。
より正確には、0.05のビン幅を使用して、上記の手法で0.1と0.15を読み取るデータポイントが同じビンに分類されることに気づきました。これ(明らかに望ましくない動作)は、おそらく「floor」機能が原因です。
以下、これを回避するための私の小さな貢献です。
bin(x,width,n)=x<=n*width? width*(n-1) + 0.5*binwidth:bin(x,width,n+1)
binwidth = 0.05
set boxwidth binwidth
plot "data.dat" u (bin($1,binwidth,1)):(1.0) smooth freq with boxes
この再帰的方法は、x> = 0の場合です。これをより条件的なステートメントで一般化して、さらに一般的なものを取得できます。
再帰的な方法を使用する必要はありません。遅いかもしれません。私の解決策は、組み込み関数intまたはfloorのユーザー定義関数rint instesdを使用することです。
rint(x)=(x-int(x)>0.9999)?int(x)+1:int(x)
この関数は、与えますrint(0.0003/0.0001)=3
、しばらくint(0.0003/0.0001)=floor(0.0003/0.0001)=2
。
どうして?Perlのint関数とパディングゼロを見てください
Born2Smileのソリューションに少し変更を加えました。
私はそれがあまり意味をなさないことを知っていますが、念のためそれを欲しがるかもしれません。データが整数で、フロートビンサイズが必要な場合(別のデータセットと比較するため、またはより細かいグリッドで密度をプロットするため)、床の内側に0〜1の乱数を追加する必要があります。そうしないと、切り上げ誤差によりスパイクが発生します。floor(x/width+0.5)
元のデータに当てはまらないパターンが作成されるため、実行されません。
binwidth=0.3
bin(x,width)=width*floor(x/width+rand(0))
ビニング関数に関しては、これまでに提供された関数の結果を期待していませんでした。つまり、ビン幅が0.001の場合、これらの関数はビンを0.0005ポイントに集中させていましたが、ビンを0.001境界に集中させるほうが直感的だと感じました。
言い換えれば、
Bin 0.001 contain data from 0.0005 to 0.0014
Bin 0.002 contain data from 0.0015 to 0.0024
...
私が思いついたビニング機能は
my_bin(x,width) = width*(floor(x/width+0.5))
以下は、提供されているビン関数のいくつかをこれと比較するためのスクリプトです。
rint(x) = (x-int(x)>0.9999)?int(x)+1:int(x)
bin(x,width) = width*rint(x/width) + width/2.0
binc(x,width) = width*(int(x/width)+0.5)
mitar_bin(x,width) = width*floor(x/width) + width/2.0
my_bin(x,width) = width*(floor(x/width+0.5))
binwidth = 0.001
data_list = "-0.1386 -0.1383 -0.1375 -0.0015 -0.0005 0.0005 0.0015 0.1375 0.1383 0.1386"
my_line = sprintf("%7s %7s %7s %7s %7s","data","bin()","binc()","mitar()","my_bin()")
print my_line
do for [i in data_list] {
iN = i + 0
my_line = sprintf("%+.4f %+.4f %+.4f %+.4f %+.4f",iN,bin(iN,binwidth),binc(iN,binwidth),mitar_bin(iN,binwidth),my_bin(iN,binwidth))
print my_line
}
これが出力です
data bin() binc() mitar() my_bin()
-0.1386 -0.1375 -0.1375 -0.1385 -0.1390
-0.1383 -0.1375 -0.1375 -0.1385 -0.1380
-0.1375 -0.1365 -0.1365 -0.1375 -0.1380
-0.0015 -0.0005 -0.0005 -0.0015 -0.0010
-0.0005 +0.0005 +0.0005 -0.0005 +0.0000
+0.0005 +0.0005 +0.0005 +0.0005 +0.0010
+0.0015 +0.0015 +0.0015 +0.0015 +0.0020
+0.1375 +0.1375 +0.1375 +0.1375 +0.1380
+0.1383 +0.1385 +0.1385 +0.1385 +0.1380
+0.1386 +0.1385 +0.1385 +0.1385 +0.1390