2013-02-21 39 views
6

Có cách nào để vẽ một hàm dựa trên các giá trị từ một tệp văn bản không?Vẽ một hàm trực tiếp từ một tệp văn bản

Tôi biết cách xác định hàm trong gnuplot rồi vẽ đồ thị nhưng đó không phải là thứ tôi cần. Tôi có một bảng với hằng số cho các hàm được cập nhật thường xuyên. Khi cập nhật này xảy ra, tôi muốn có thể chạy một kịch bản vẽ một hình với đường cong mới này. Vì có rất ít số liệu để vẽ nên tôi muốn tự động hóa quy trình.

Dưới đây là một bảng ví dụ với các hằng số:

location a b c 
1  1 3 4 
2 

Có hai cách tôi nhìn thấy để giải quyết vấn đề nhưng tôi không biết nếu và làm thế nào họ có thể được thực hiện.

  1. tôi sau đó có thể sử dụng awk để tạo ra chuỗi: f(x)=1(x)**2+3(x)+4, hãy viết nó vào một tập tin và bằng cách nào đó làm cho gnuplot đọc tập tin và cốt truyện mới này trên một x phạm vi nhất định.
  2. hoặc sử dụng awk bên trong gnuplot một cái gì đó như f(x) = awk /1/ {print "f(x)="$2 v.v. hoặc sử dụng awk trực tiếp trong lệnh lô.

Tôi gặp bất kỳ trường hợp nào, tôi gặp khó khăn và không tìm thấy giải pháp cho vấn đề này trực tuyến, bạn có đề xuất nào không?

+0

Tại sao bạn tìm kiếm giải pháp 1 dòng? – mgilson

+0

Khi tôi sử dụng 'gnuplot', tôi luôn gọi nó từ bên trong' Perl'. Nếu đây không phải là một tùy chọn vì lý do gì, tôi khuyên bạn nên gọi 'awk' từ bên trong tập lệnh 'gnuplot' của bạn. Xem [tại đây] (http://stackoverflow.com/questions/12846717/using-awk-or-other-shell-command-inside-gnuplot-function) và [tại đây] (http: //security.riit.tsinghua. edu.cn/~bhyang/ref/gnuplot/datafile3-e.html) để biết cách thực hiện điều này. – Steve

Trả lời

0
awk '/1/ {print "plot "$2"*x**2+"$3"*x+"$4}' | gnuplot -persist 

sẽ chọn dòng và vẽ nó

1

Câu hỏi này (gnuplot store one number from data file into variable) đã có một số gợi ý cho tôi trong câu trả lời đầu tiên.

Trong trường hợp của tôi, tôi có tệp chứa thông số cho parabola. Tôi đã lưu các tham số trong các biến gnuplot. Sau đó, tôi vẽ hàm chứa các biến tham số cho mỗi dấu thời gian.

#!/usr/bin/gnuplot 

datafile = "parabola.txt" 

set terminal pngcairo size 1000,500 
set xrange [-100:100] 
set yrange [-100:100] 
titletext(timepar, apar, cpar) = sprintf("In timestep %d we have parameter a = %f, parameter c = %f", timepar, apar, cpar) 

do for [step=1:400] { 
    set output sprintf("parabola%04d.png", step) 

    # read parameters from file, where the first line is the header, thus the +1 
    a=system("awk '{ if (NR == " . step . "+1) printf \"%f\", $1}' " . datafile) 
    c=system("awk '{ if (NR == " . step . "+1) printf \"%f\", $2}' " . datafile) 

    # convert parameters to numeric format 
    a=a+0. 
    c=c+0. 

    set title titletext(step, a, c) 

    plot c+a*x**2 
} 

Điều này cho phép một loạt các file png gọi parabola0001.png, parabola0002.png, parabola0003.png, ..., mỗi hiển thị một parabol với các thông số đọc từ tập tin gọi là parabola.txt. Tiêu đề chứa các tham số của bước thời gian đã cho.

Đối với sự hiểu biết về chức năng gnuplot system() bạn phải biết rằng:

  • thứ bên trong dấu ngoặc kép không được phân tích bằng gnuplot
  • dấu chấm là cho concatenating chuỗi trong gnuplot
  • các dấu ngoặc kép cho awk printf lệnh phải được thoát, để ẩn chúng khỏi trình phân tích cú pháp gnuplot

Để kiểm tra tập lệnh gnuplot này, hãy lưu vào một tệp có tên tùy ý, ví dụ: parabolaplot.gplot và làm cho nó thực thi (chmad a+x parabolaplot.gplot).Các tập tin parabola.txt có thể được tạo ra với

awk 'BEGIN {for (i=1; i<=1000; i++) printf "%f\t%f\n", i/200, i/100}' > parabola.txt

3

possibilty khác để có một phiên bản hơi chung chung cho điều này, bạn có thể làm như sau:

Giả sử, các thông số được lưu trữ trong một tập tin parameters.dat với người đầu tiên dòng chứa các tên biến và tất cả các tham số khác, như

location a b c 
1  1 3 4 

Tệp kịch bản trông giống như sau:

file = 'parameters.dat' 
par_names = system('head -1 '.file) 
par_cnt = words(par_names) 

# which parameter set to choose 
par_line_num = 2 
# select the respective string 
par_line = system(sprintf('head -%d ', par_line_num).file.' | tail -1') 
par_string = '' 
do for [i=1:par_cnt] { 
    eval(word(par_names, i).' = '.word(par_line, i)) 
} 
f(x) = a*x**2 + b*x + c 

plot f(x) title sprintf('location = %d', location) 
Các vấn đề liên quan