2010-08-19 8 views
16

gnuplot을 사용하여 데이터 목록을 '.dat'파일에 쓰고이를 의도적으로 플로팅하는 프로그램을 작성했습니다. 자동으로 코드 플롯을 만드는 방법이 있습니까? 내 출력의 형식은 : 이상적으로C 코드를 자동으로 그래프로 만들기

x-coord analytic approximation 
x-coord analytic approximation 
x-coord analytic approximation 
x-coord analytic approximation 
x-coord analytic approximation 
.... 

, 내가 그래프는 또한 X-라벨, Y-레이블 (내 C 코드에서 변경 될 수 있습니다) 제목으로 인쇄 될 코드를 실행할 때. 많은 감사합니다.

+1

아마'system' 기능을 확인하십시오. – sje397

답변

32

gnuplot과 관련된 다른 것을 검색하면서이 문제가 발생했습니다. 비록 오래된 질문이지만, 나는 약간의 샘플 코드를 제공 할 것이라고 생각했다. 나는 이것을 내 프로그램에 사용하고, 나는 그것이 꽤 깔끔한 일을한다고 생각한다. AFAIK,이 PIPEing은 Unix 시스템에서만 작동합니다 (아래 Windows 사용자 편집 참조). 내 gnuplot 설치는 우분투 저장소의 기본 설치입니다. 내 응용 프로그램에서

#include <stdlib.h> 
#include <stdio.h> 
#define NUM_POINTS 5 
#define NUM_COMMANDS 2 

int main() 
{ 
    char * commandsForGnuplot[] = {"set title \"TITLEEEEE\"", "plot 'data.temp'"}; 
    double xvals[NUM_POINTS] = {1.0, 2.0, 3.0, 4.0, 5.0}; 
    double yvals[NUM_POINTS] = {5.0 ,3.0, 1.0, 3.0, 5.0}; 
    FILE * temp = fopen("data.temp", "w"); 
    /*Opens an interface that one can use to send commands as if they were typing into the 
    *  gnuplot command line. "The -persistent" keeps the plot open even after your 
    *  C program terminates. 
    */ 
    FILE * gnuplotPipe = popen ("gnuplot -persistent", "w"); 
    int i; 
    for (i=0; i < NUM_POINTS; i++) 
    { 
    fprintf(temp, "%lf %lf \n", xvals[i], yvals[i]); //Write the data to a temporary file 
    } 

    for (i=0; i < NUM_COMMANDS; i++) 
    { 
    fprintf(gnuplotPipe, "%s \n", commandsForGnuplot[i]); //Send commands to gnuplot one by one. 
    } 
    return 0; 
} 

편집은 또한 호출 프로그램이 종료 될 때까지 플롯이 표시되지 않는 문제 다 퉜다. 이 문제를 해결하려면 fprintf을 사용한 후 fflush(gnuplotPipe)을 추가하여 최종 명령을 보내십시오.

나는 Windows 사용자가 popen 대신 _popen을 사용할 수 있음을 알았지 만, Windows가 설치되어 있지 않기 때문에이를 확인할 수 없습니다.

편집 2

하나는 문자 "E"다음에 데이터 포인트 다음에 plot '-' 명령을의 gnuplot 전송하여 파일에 기록하는 것을 방지 할 수 있습니다.

내가이 일을하는 방법을 많이,이 일을 가장 간단한 방법은 (stdlib.h에서) 시스템을()를 사용하여 C에서 함수가 될 것이다 먼저의 gnuplot을 본 적이 있지만

fprintf(gnuplotPipe, "plot '-' \n"); 
int i; 

for (int i = 0; i < NUM_POINTS; i++) 
{ 
    fprintf(gnuplotPipe, "%lf %lf\n", xvals[i], yvals[i]); 
} 

fprintf(gnuplotPipe, "e"); 
+0

이 답변이 발표 된 이래로 정말 오랜 시간이 걸렸지 만 두 번째 편집 코드에서 for 루프를 사용하여 명령을 추가하는'commandsForGnuplot'을 사용했다. , 그리고 그것은 구획하지만 명령 (제목, xlabel 또는 ylabel) 중 하나를 추가하지 않습니다. 그런 식으로하지 않으면 어떻게 추가 할 수 있습니까? –

5

gnuplot 스크립트를 생성하고 gnuplot을 실행하는 프로세스를 생성하여 명령 행에서이 스크립트를 플롯하거나 제공된 인터페이스 중 하나를 사용할 수 있습니다. C의 경우, 여기에 해당 니콜라스 Devillard에서 POSIX 파이프 기반의 인터페이스가 : http://ndevilla.free.fr/gnuplot/ ... 그리고 iostream 기반의 C++ 버전은 자식을 통해 사용할 수있다 (참조 : http://www.stahlke.org/dan/gnuplot-iostream/를)

아마 가장 쉬운 가장 휴대 성을 그래도 gnuplot을 호출하여 스크립트를 그릴 수 있습니다. sje397이 언급했듯이 stdlib.h에서 system() 호출에 대한 설명서를 확인하십시오.

사이드 노트에는 응용 프로그램에서 사용할 수있는 플로팅 데이터 세트 용 라이브러리 인 libplot을 제공하는 GNU plotutils도 있습니다. 참고 : http://www.gnu.org/software/plotutils/

+1

Im이 모든 설명서에 대해 잘 이해하고 있지는 않지만 system()에 대한 선언을 발견했습니다. int system (const char * command); 그러면 다음과 같은 내용을 추가 할 수 있습니까? 시스템 (gnuplot plot "data_set.dat": 줄을 사용하여 1 : 2); – JMzance

+1

결국 나는 이런 식으로 갔다. – JMzance

+1

#include "gnuplot_i.h" int main (void) { FILE * outFile; outFile = fopen ("Flight_Path.dat", "w"); /* 출력 파일에 인쇄하는 반복 루프 : example.dat */ fclose (outFile); gnuplot_ctrl * k; k = gnuplot_init(); gnuplot_set_xlabel (k, "x"); gnuplot_set_ylabel (k, "y"); gnuplot_cmd (k, input_x); gnuplot_cmd (k, input_y); gnuplot_cmd (k, "제목 \"끌기가있는 탄도 \ ""); gnuplot_cmd (K '플롯 \ "Flight_Path.dat \"1 이용한 2 표제 \ " 슬립 (7) \ 비행 경로 \"라인을, gnuplot_close (K) 복귀 0; } – JMzance

2

스크립트를 작성하고 "name.gp"(이름이나 확장명이 아닌)로 저장하십시오.
간단한 스크립트는

plot 'Output.dat' with lines 

이 스크립트 파일을 저장 한 후, 당신의 코드 끝에
system("gnuplot -p 'name.gp'");
를 추가 할 것이다.
간단합니다.

0

필자는 임시 파일 사용을 피하면서 float 배열을 플롯하기위한 대답을 채택했습니다. 그 안에는 float* data_이 배열이고 그 크기는 size_t size_입니다. 바라건대 누군가에게 도움이되기를 바랍니다!

건배,
안드레스

void plot(const char* name="FloatSignal"){ 
    // open persistent gnuplot window 
    FILE* gnuplot_pipe = popen ("gnuplot -persistent", "w"); 
    // basic settings 
    fprintf(gnuplot_pipe, "set title '%s'\n", name); 
    // fill it with data 
    fprintf(gnuplot_pipe, "plot '-'\n"); 
    for(size_t i=0; i<size_; ++i){ 
    fprintf(gnuplot_pipe, "%zu %f\n", i, data_[i]); 
    } 
    fprintf(gnuplot_pipe, "e\n"); 
    // refresh can probably be omitted 
    fprintf(gnuplot_pipe, "refresh\n"); 
}