gnuplotを使用したヒストグラム?


202

私の.datファイルに既に適切にビニングされたデータがある場合、gnuplotでヒストグラムを作成する方法を知っています(「ボックス付き」を使用するだけです)。数値のリストを取り、gnuplotがユーザーが提供する範囲とビンサイズに基づいてヒストグラムを提供する方法はありますか?


2
答えが得られない場合は、そのようなことをするためのツールが他にもあります。私はRoot(root.cern.ch)を使用しています。他の多くはRを使用しており、少なくともいくつかのオプションがあります。
dmckee ---元モデレーターの子猫2010

1
Binは、ヒストグラムの各バーについてまとめて収集された値の範囲です。各ビンには下限と上限があり、その範囲の値を持つすべてのデータはそのバーに向かってカウントされます。ビン化とは、データファイルが各ビン内に含まれるデータポイントの数によって既に構成されているため、ヒストグラムとしてプロットする準備ができていることを意味します。
2018年

回答:


225

はい、それは非常に隠されていますが、素早く簡単です:

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変数を設定します。


11
以下の@ChrisWの回答は、Gnuplotでヒストグラムを作成したい人にとって重要なポイントになると思います。
Abhinav 2013年

2
非常に注意してください。これは、セットに「欠落」したビンがない場合にのみ機能します...この関数は、欠落したビンのy値を前の欠落していないビンのy値に修正します。これは誤解を招く可能性があります!!!
PinkFloyd 2017年

1
set boxwidth binwidth上記に追加します。本当に助かりました。
Jaakko

90

Born2Smileの非常に便利な回答にいくつかの修正/追加があります。

  1. ビンが空になると、隣接するビンのボックスが誤ってそのスペースに拡張されました。これを使用しないでくださいset boxwidth binwidth
  2. Born2Smileのバージョンでは、ビンは下限を中心としてレンダリングされます。厳密に言えば、それらは下限から上限に拡張する必要があります。これはbin関数を変更することで修正できます:bin(x,width)=width*floor(x/width) + width/2.0

10
実際、その2番目の部分はbin(x,width)=width*floor(x/width) + binwidth/2.0(浮動小数点の計算)
bgw 2010

8
つまりbin(x,width)=width*floor(x/width) + width/2.0width引数として渡す場合は、それを使用します。:-)
Mitar 2013年

78

非常に注意してください。このページのすべての回答は、ビニングの開始場所(必要に応じて、左端のビンの左端)をユーザーの手から暗黙的に決定しています。ユーザーがデータをビニングするためのこれらの機能のいずれかと、ビニングの開始場所に関する自分の決定を組み合わせている場合(上記にリンクされているブログで行われているように)、上記の機能はすべて正しくありません。「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は本当に左側のビンに該当します。

  • この関数は、それを左ビンの中心(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で発生する場合にのみ正しいです。


48

このようなグラフをプロットしますか? ここに画像の説明を入力してください はい?その後、私のブログ記事を見ることができます: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

10

いつものように、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

7

このディスカッションは非常に役に立ちましたが、「丸め」の問題が発生しました。

より正確には、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の場合です。これをより条件的なステートメントで一般化して、さらに一般的なものを取得できます。


6

再帰的な方法を使用する必要はありません。遅いかもしれません。私の解決策は、組み込み関数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関数とパディングゼロを見てください


4

Born2Smileのソリューションに少し変更を加えました。

私はそれがあまり意味をなさないことを知っていますが、念のためそれを欲しがるかもしれません。データが整数で、フロートビンサイズが必要な場合(別のデータセットと比較するため、またはより細かいグリッドで密度をプロットするため)、床の内側に0〜1の乱数を追加する必要があります。そうしないと、切り上げ誤差によりスパイクが発生します。floor(x/width+0.5)元のデータに当てはまらないパターンが作成されるため、実行されません。

binwidth=0.3
bin(x,width)=width*floor(x/width+rand(0))

1
このような状況に遭遇したことはありませんが、後で発生する可能性があります。float sdを使用して正規分布整数でテストし、bin = 1、bin = sdを使用してヒストグラムをプロットできます。rand(0)トリックを使用した場合と使用しない場合の結果を確認してください。私は彼の原稿をレビューしているときに共同編集者の間違いを見つけました。彼の結果は、まったくナンセンスから予想通り美しい姿に変わった。
path4 14

わかりました、たぶん説明は非常に短いので、より具体的なテストケースなしでは理解できません。私はあなたの回答を少し編集して、投票を取り消すことができるようにします;)
クリストフ

正規分布の整数を考えます。それらは整数なので、それらの多くは同じx / widthになります。その数が1.3だとしましょう。floor(x / width + 0.5)では、それらすべてがビン1に割り当てられますが、密度に関して1.3が実際に意味するのは、それらの70%がビン1にあり、30%がビン2にあるということです。rand(0 )適切な密度を維持します。したがって、0.5はスパイクを作成し、rand(0)はそれを維持します。0.5ではなくrand(0)を使用すると、hsxzによる数値がはるかにスムーズになると思います。切り上げるだけでなく、摂動なしで切り上げます。
path4 2014

3

ビニング関数に関しては、これまでに提供された関数の結果を期待していませんでした。つまり、ビン幅が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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.