Biểu đồ sử dụng gnuplot?


202

Tôi biết cách tạo biểu đồ (chỉ sử dụng "với hộp") trong gnuplot nếu tệp .dat của tôi đã có dữ liệu được đánh dấu đúng. Có cách nào để lấy danh sách các số và gnuplot cung cấp biểu đồ dựa trên phạm vi và kích thước bin mà người dùng cung cấp không?


2
Nếu bạn không nhận được câu trả lời, có những công cụ khác dùng để làm những việc đó. Tôi sử dụng Root ( root.cern.ch ) nhiều người khác ở đây sử dụng R và có ít nhất một vài tùy chọn khác.
dmckee --- ex-moderator mèo con

1
Bin là phạm vi của các giá trị được thu thập cùng nhau cho mỗi thanh trong biểu đồ. Mỗi thùng có giới hạn dưới và trên và tất cả dữ liệu có giá trị trong phạm vi đó sẽ được tính vào thanh đó. Binned có nghĩa là tệp dữ liệu của tôi đã được sắp xếp theo số lượng điểm dữ liệu nằm trong mỗi thùng để nó sẵn sàng được vẽ như một biểu đồ.
mary

Câu trả lời:


225

vâng, và nó nhanh chóng và đơn giản mặc dù rất ẩn:

binwidth=5
bin(x,width)=width*floor(x/width)

plot 'datafile' using (bin($1,binwidth)):(1.0) smooth freq with boxes

kiểm tra help smooth freqđể xem tại sao ở trên làm cho một biểu đồ

để đối phó với các phạm vi chỉ cần đặt biến xrange.


11
Tôi nghĩ rằng câu trả lời của @ ChrisW dưới đây mang đến một điểm quan trọng cần chú ý cho bất kỳ ai muốn tạo Biểu đồ trong Gnuplot.
Abhinav

2
Hãy cẩn thận, điều này chỉ hoạt động nếu không có thùng "thiếu" trong bộ ... Hàm này sửa giá trị y của thùng bị thiếu thành giá trị y của thùng không bị thiếu trước đó. Điều này có thể rất sai lệch !!!
PinkFloyd

1
Tôi sẽ thêm set boxwidth binwidthvào ở trên. Nó thực sự hữu ích cho tôi.
Jaakko

90

Tôi có một vài chỉnh sửa / bổ sung cho câu trả lời rất hữu ích của Born2Smile:

  1. Thùng rỗng khiến hộp cho thùng bên cạnh mở rộng không chính xác vào không gian của nó; tránh điều này bằng cách sử dụngset boxwidth binwidth
  2. Trong phiên bản của Born2Smile, các thùng được hiển thị làm trung tâm ở giới hạn dưới của chúng. Nghiêm khắc họ nên mở rộng từ giới hạn dưới đến giới hạn trên. Điều này có thể được sửa chữa bằng cách sửa đổi binchức năng:bin(x,width)=width*floor(x/width) + width/2.0

10
Trên thực tế, phần thứ hai phải là bin(x,width)=width*floor(x/width) + binwidth/2.0(tính toán dấu phẩy động)
bgw

8
Bạn có ý nghĩa bin(x,width)=width*floor(x/width) + width/2.0. Nếu chúng ta đang vượt qua widthnhư một đối số, sau đó sử dụng nó. :-)
Mitar

78

Hãy cẩn thận: tất cả các câu trả lời trên trang này đều hoàn toàn đưa ra quyết định nơi bắt đầu đóng thùng - cạnh trái của thùng ngoài cùng bên trái, nếu bạn muốn - ra khỏi tay người dùng. Nếu người dùng đang kết hợp bất kỳ chức năng nào trong số các chức năng này để tạo dữ liệu với quyết định của riêng mình về việc bắt đầu tạo thùng (như được thực hiện trên blog được liên kết ở trên) thì các chức năng trên đều không chính xác. Với điểm bắt đầu tùy ý để tạo thùng 'Min', chức năng chính xác là:

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

Bạn có thể thấy lý do tại sao điều này là chính xác theo tuần tự (nó giúp vẽ một vài thùng và một điểm ở đâu đó trong một trong số chúng). Trừ Min khỏi điểm dữ liệu của bạn để xem phạm vi đóng gói của nó là bao xa. Sau đó chia cho băng thông để bạn làm việc hiệu quả trong các đơn vị 'thùng'. Sau đó, 'sàn' kết quả để đi đến cạnh bên trái của thùng đó, thêm 0,5 để vào giữa thùng, nhân với chiều rộng để bạn không còn làm việc trong các đơn vị thùng mà ở quy mô tuyệt đối một lần nữa, sau đó cuối cùng thêm lại vào phần bù Min mà bạn đã trừ khi bắt đầu.

Xem xét chức năng này trong hành động:

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

ví dụ: giá trị 1.1 thực sự rơi vào thùng bên trái:

  • chức năng này ánh xạ chính xác nó vào trung tâm của thùng bên trái (0,75);
  • Câu trả lời của Born2Smile, bin (x) = width * floor (x / width), ánh xạ không chính xác thành 1;
  • Câu trả lời của mas90, bin (x) = width * floor (x / width) + bin thong / 2.0, ánh xạ không chính xác đến 1.5.

Câu trả lời của Born2Smile chỉ đúng nếu ranh giới bin xảy ra tại (n + 0,5) * bin thong (trong đó n chạy trên số nguyên). Câu trả lời của mas90 chỉ đúng nếu ranh giới bin xảy ra ở n * bin thong.


48

Bạn có muốn vẽ đồ thị như thế này không? nhập mô tả hình ảnh ở đây Đúng? Sau đó, bạn có thể xem bài viết trên blog của tôi: http://gnuplot-surprising.blogspot.com/2011/09/statistic-analysis-and-histogram.html

Các dòng chính từ mã:

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

Như thường lệ, Gnuplot là một công cụ tuyệt vời để vẽ đồ thị trông ngọt ngào và nó có thể được thực hiện để thực hiện tất cả các loại tính toán. Tuy nhiên , nó được dùng để vẽ dữ liệu thay vì dùng làm máy tính và thường sử dụng chương trình bên ngoài (ví dụ Octave) để thực hiện các phép tính "phức tạp" hơn, lưu dữ liệu này vào tệp, sau đó sử dụng Gnuplot để sản xuất đồ thị. Đối với vấn đề trên, hãy kiểm tra chức năng "hist" đang sử dụng Octave [freq,bins]=hist(data), sau đó vẽ biểu đồ này trong Gnuplot bằng cách sử dụng

set style histogram rowstacked gap 0
set style fill solid 0.5 border lt -1
plot "./data.dat" smooth freq with boxes

7

Tôi đã thấy cuộc thảo luận này cực kỳ hữu ích, nhưng tôi đã trải qua một số vấn đề "làm tròn".

Chính xác hơn, bằng cách sử dụng độ rộng 0,05, tôi nhận thấy rằng, với các kỹ thuật được trình bày ở trên, các điểm dữ liệu đọc 0,1 và 0,15 rơi vào cùng một thùng. Điều này (rõ ràng là hành vi không mong muốn) rất có thể là do chức năng "sàn".

Sau đây là đóng góp nhỏ của tôi để cố gắng phá vỡ điều này.

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

Phương thức đệ quy này là cho x> = 0; người ta có thể khái quát điều này với các tuyên bố có điều kiện hơn để có được một cái gì đó tổng quát hơn.


6

Chúng ta không cần sử dụng phương pháp đệ quy, nó có thể chậm. Giải pháp của tôi là sử dụng hàm do người dùng định nghĩa rint instesd của hàm Barsinsic int hoặc floor.

rint(x)=(x-int(x)>0.9999)?int(x)+1:int(x)

Chức năng này sẽ cung cấp rint(0.0003/0.0001)=3, trong khi int(0.0003/0.0001)=floor(0.0003/0.0001)=2.

Tại sao? Xin vui lòng nhìn vào chức năng Perl int và số không đệm


4

Tôi có một chút sửa đổi đối với giải pháp của Born2Smile.

Tôi biết điều đó không có nhiều ý nghĩa, nhưng bạn có thể muốn nó chỉ trong trường hợp. Nếu dữ liệu của bạn là số nguyên và bạn cần kích thước thùng phao (có thể để so sánh với một tập hợp dữ liệu khác hoặc mật độ lô trong lưới mịn hơn), bạn sẽ cần thêm một số ngẫu nhiên từ 0 đến 1 bên trong tầng. Nếu không, sẽ có đột biến do lỗi làm tròn. floor(x/width+0.5)sẽ không làm vì nó sẽ tạo ra mẫu không đúng với dữ liệu gốc.

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

1
Bạn đã không gặp phải tình huống như vậy, nhưng bạn có thể sau này. Bạn có thể kiểm tra nó với các số nguyên được phân phối bình thường với biểu đồ float và biểu đồ lô với bin = 1 và bin = sd Xem những gì bạn nhận được có và không có thủ thuật rand (0). Tôi bắt gặp lỗi của cộng tác viên khi xem lại bản thảo của anh ấy. Kết quả của anh đã thay đổi từ hoàn toàn vô nghĩa thành một con số đẹp như mong đợi.
path4

Ok, có lẽ lời giải thích quá ngắn, đến nỗi người ta không thể hiểu nó nếu không có trường hợp kiểm tra cụ thể hơn. Tôi sẽ thực hiện một chỉnh sửa ngắn cho câu trả lời của bạn để tôi có thể hoàn tác lại phần dưới;)
Christoph

Xem xét các số nguyên của phân phối bình thường. Vì chúng là số nguyên, nhiều trong số chúng sẽ có cùng x / width. Hãy nói rằng con số đó là 1,3. Với sàn (x / width + 0,5), tất cả chúng sẽ được gán cho bin 1. Nhưng điều 1.3 thực sự có nghĩa là về mật độ là 70% trong số chúng nên nằm trong thùng 1 và 30% trong thùng 2. rand (0 ) giữ mật độ thích hợp. Vì vậy, 0,5 tạo ra các gai và rand (0) giữ cho nó đúng. Tôi đặt cược con số của hsxz sẽ mượt mà hơn nhiều khi sử dụng rand (0) thay vì 0,5. Nó không chỉ làm tròn, mà còn làm tròn mà không bị nhiễu loạn.
path4

3

Đối với các chức năng tạo thùng, tôi không mong đợi kết quả của các chức năng được cung cấp cho đến nay. Cụ thể, nếu độ rộng băng thông của tôi là 0,001, các chức năng này đã tập trung vào các thùng trên 0,0005 điểm, trong khi tôi cảm thấy nó trực quan hơn khi đặt các thùng ở giữa ranh giới 0,001.

Nói cách khác, tôi muốn có

Bin 0.001 contain data from 0.0005 to 0.0014
Bin 0.002 contain data from 0.0015 to 0.0024
...

Hàm binning tôi nghĩ ra là

my_bin(x,width)     = width*(floor(x/width+0.5))

Đây là tập lệnh để so sánh một số hàm bin được cung cấp với hàm này:

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
}

và đây là đầu ra

   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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.