.datファイルにすでに適切にビニングされたデータがある場合は、gnuplotでヒストグラムを作成する方法を知っています(「ボックス付き」を使用するだけです)。数値のリストを取得し、gnuplotにユーザーが提供する範囲とビンサイズに基づいたヒストグラムを提供させる方法はありますか?
10 に答える
はい、そして非常に隠されていますが、その迅速でシンプルです:
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変数を設定するだけです。
Born2Smileの非常に有用な答えにいくつかの修正/追加があります:
- ビンが空になると、隣接するビンのボックスが誤ってそのスペースに拡張されました。これを使用して避けてください
set boxwidth binwidth
- Born2Smileのバージョンでは、ビンは下限を中心としてレンダリングされます。厳密には、それらは下限から上限まで拡張する必要があります。
bin
これは、関数を変更することで修正できます。bin(x,width)=width*floor(x/width) + width/2.0
非常に注意してください。このページのすべての回答は、ビニングを開始する場所(必要に応じて、左端のビンの左端)をユーザーの手から暗黙的に決定しています。ユーザーがデータをビニングするためのこれらの機能のいずれかを、ビニングを開始する場所に関する自分の決定と組み合わせている場合(上記にリンクされているブログで行われているように)、上記の機能はすべて正しくありません。'Min'をビニングするための任意の開始点を使用すると、正しい関数は次のようになります。
bin(x) = width*(floor((x-Min)/width)+0.5) + Min
これが順番に正しい理由がわかります(いくつかのビンとそれらの1つのどこかにポイントを描画するのに役立ちます)。データポイントから最小値を引いて、ビニング範囲にどれだけ入っているかを確認します。次に、binwidthで除算して、「bins」の単位で効果的に作業できるようにします。次に、結果を「フロア」してそのビンの左端に移動し、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は本当に左側のビンに分類されます。
- この関数は、それを左のビンの中心(0.75)に正しくマップします。
- Born2Smileの答えbin(x)= width * floor(x / width)は、誤って1にマップします。
- mas90の答え、bin(x)= width * floor(x / width)+ binwidth / 2.0は、誤って1.5にマップします。
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を読み取るデータポイントが同じビンに含まれることに気付きました。これ(明らかに望ましくない動作)は、「床」関数が原因である可能性が最も高いです。
これからは、これを回避するための私の小さな貢献です。
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のユーザー定義関数rintinstesdを使用することです。
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))
提供されているbin関数のいくつかをこれと比較するためのスクリプトを次に示します。
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
同じデータセットのビンの数が異なると、データの異なる特徴が明らかになる可能性があります。
残念ながら、ビンの数を決定できる普遍的な最良の方法はありません。
強力な方法の1つは、フリードマン・ダイアコニス規則です。これは、他の多くの選択肢の中でも、特定のデータセットの統計に基づいてビンの数を自動的に決定します。
gnuplot
したがって、以下を使用して、スクリプトでフリードマン・ダイアコニス規則を利用できます。
サンプルの単一の列を含むファイルがあるとしますsamplesFile
。
# samples
0.12345
1.23232
...
以下( ChrisWの回答に基づく)を既存のgnuplot
スクリプトに埋め込むことができます。
...
## preceeding gnuplot commands
...
#
samples="$samplesFile"
stats samples nooutput
N = floor(STATS_records)
samplesMin = STATS_min
samplesMax = STATS_max
# Freedman–Diaconis formula for bin-width size estimation
lowQuartile = STATS_lo_quartile
upQuartile = STATS_up_quartile
IQR = upQuartile - lowQuartile
width = 2*IQR/(N**(1.0/3.0))
bin(x) = width*(floor((x-samplesMin)/width)+0.5) + samplesMin
plot \
samples u (bin(\$1)):(1.0/(N*width)) t "Output" w l lw 1 smooth freq