문제

내 .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 변수를 설정합니다.

다른 팁

Born2Smile의 매우 유용한 답변에 몇 가지 수정/추가가 있습니다.

  1. 빈 쓰레기통은 인접한 빈이 공간으로 잘못 확장되었습니다. 사용하지 마십시오 set boxwidth binwidth
  2. Born2Smile의 버전에서 빈은 하한을 중심으로 렌더링됩니다. 엄격히 그들은 하한에서 상한으로 확장해야합니다. 이것은 수정하여 수정할 수 있습니다 bin 기능: bin(x,width)=width*floor(x/width) + width/2.0

매우 조심하십시오 :이 페이지의 모든 답변은 바이닝이 시작되는 위치를 암시 적으로 결정하고 있습니다. 사용자가 Binning 데이터에 대한 이러한 기능을 Binning이 시작되는 위치에 대한 자신의 결정과 결합하는 경우 (위에 연결된 블로그에서 수행되는 것처럼) 위의 기능은 모두 잘못되었습니다. Binning 'Min'을위한 임의의 시작점을 사용하면 올바른 기능은 다음과 같습니다.

bin(x) = width*(floor((x-Min)/width)+0.5) + Min

이것이 왜 순차적으로 올바른지 알 수 있습니다 (몇 개의 쓰레기통과 그 중 하나의 어딘가에 포인트를 그리는 데 도움이됩니다). 데이터 포인트에서 최소를 빼서 바이닝 범위가 얼마나 멀리 떨어져 있는지 확인하십시오. 그런 다음 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의 답변, 빈 (x) = 너비*바닥 (x/width)은 1에 잘못지도;
  • MAS90의 답변, 빈 (x) = 너비*바닥 (x/width) + binwidth/2.0은 1.5로 잘못 맵핑됩니다.

Born2Smile의 답변은 빈 경계가 (n+0.5)*binwidth (N이 정수 위로 실행되는 경우)에서 발생하는 경우에만 정확합니다. MAS90의 대답은 N*binwidth에서 빈 경계가 발생하는 경우에만 정확합니다.

이와 같은 그래프를 플로팅 하시겠습니까?enter image description here예? 그런 다음 내 블로그 기사를 볼 수 있습니다. 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"기능이 옥타브를 사용하여 확인하십시오. [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입니다. 더 일반적인 것을 얻기 위해 더 조건부 진술로 이것을 일반화 할 수 있습니다.

우리는 재귀 방법을 사용할 필요가 없으며 느릴 수 있습니다. 내 솔루션은 Instrinsic Function 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 기능 및 패딩 0

Born2Smile의 솔루션을 약간 수정했습니다.

나는 그것이 의미가 없다는 것을 알고 있지만 만일을 대비하여 원할 수도 있습니다. 데이터가 정수이고 플로트 빈 크기가 필요한 경우 (아마도 다른 데이터 세트와 비교하거나 미세한 그리드의 플롯 밀도를 비교할 수 있음) 층 내부에서 0과 1 사이의 임의 숫자를 추가해야합니다. 그렇지 않으면 반올림 오류로 인해 스파이크가 발생합니다. floor(x/width+0.5) 원래 데이터에 맞지 않는 패턴을 생성하기 때문에 수행되지 않습니다.

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

비닝 함수와 관련하여 지금까지 제공되는 기능의 결과는 기대하지 않았습니다. 즉, 내 binwidth가 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
...

내가 생각해 낸 바이닝 기능은 IS입니다

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top