내 .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
이것이 순차적으로 올바른 이유를 알 수 있습니다 (몇 개의 쓰레기통과 그 안에 어딘가에 점을 그리는 데 도움이 됨). 데이터 포인트에서 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 값은 실제로 왼쪽 빈에 해당합니다.
Binn 경계가 (n + 0.5) * binwidth (n이 정수를 넘음)에서 발생하는 경우 Born2Smile의 답은 정확합니다. bin 경계가 n * binwidth에서 발생하는 경우에만 mas90의 답이 정확합니다.
이와 같은 그래프를 그리시겠습니까? 예? 그런 다음 내 블로그 기사를 볼 수 있습니다 : 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은 달콤한 그래프를 그리는 환상적인 도구이며 모든 종류의 계산을 수행 할 수 있습니다. 그러나 이는 계산기 역할을하기보다는 데이터를 플로팅하기위한 것이며 외부 프로그램 (예 : 옥타브)을 사용하여보다 "복잡한"계산을 수행하고이 데이터를 파일에 저장 한 다음 Gnuplot을 사용하여 생성하는 것이 더 쉽습니다. 그래프. 위의 문제에 대해서는 "hist"기능이 Octave using 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의 사용자 정의 함수 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
.
왜? 제발 봐 펄 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