2010-08-19 6 views
16

Я написал программу, которая записывает список данных в файл «.dat», с тем чтобы затем построить его отдельно с помощью gnuplot. Есть ли способ сделать мой код заглавным? Мой выход имеет вида:Создание C-графика на графике автоматически

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

В идеале, когда я запускаю код график будет также распечатан с й-меткой, у метки и заголовок (который может быть изменен из моего кода C). Большое спасибо.

+1

Может проверить 'system' функцию. – sje397

ответ

32

Я столкнулся с этим, ища что-то еще относительно gnuplot. Несмотря на то, что это старый вопрос, я думал, что внес свой пример кода. Я использую это для моей программы, и я думаю, что это довольно красивая работа. AFAIK, эта PIPEing работает только в системах Unix (см. Ниже приведенное ниже для пользователей Windows). Моя установка gnuplot является установкой по умолчанию из репозитория Ubuntu.

#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; 
} 

EDIT

В моем приложении, я также столкнулся с проблемой, что сюжет не появляется, пока вызывающая программа не будет закрыта. Чтобы обойти это, добавьте fflush(gnuplotPipe) после того, как вы использовали fprintf, чтобы отправить его окончательную команду.

Я также видел, что пользователи Windows могут использовать _popen вместо popen - однако я не могу подтвердить это, поскольку у меня нет установленной Windows.

EDIT 2

можно избежать того, чтобы записать в файл, отправив Gnuplot в plot '-' после команды точками данных, за которой следует буква «е».

например.

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 с командамиForGnuplot в нем для добавления команд , но он не добавляет никаких команд (заголовок, xlabel или ylabel). Как я могу добавить их, если не так? Пожалуйста. –

5

Вы можете создать скрипт gnuplot и запустить процесс, запускающий gnuplot, для построения этого сценария из командной строки или вы можете использовать один из предоставленных интерфейсов. Для C, существует POSIX труб на основе интерфейса от Nicolas Devillard доступны здесь: http://ndevilla.free.fr/gnuplot/ ... и C версии iostream на основе ++ доступна через мерзавец (см: http://www.stahlke.org/dan/gnuplot-iostream/)

самые портативные и, вероятно, самый простой путь все равно будет вызывать gnuplot для построения сценария. Как упоминалось в sje397, проверьте свою документацию на вызов system() в stdlib.h.

На боковой панели есть также GNU plotutils, который предлагает libplot, библиотеку для построения наборов данных, которую вы можете использовать в своем приложении. См.: http://www.gnu.org/software/plotutils/

+1

Я не фантастически понимаю все эти материалы документации, но я нашел объявление для системы(): 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, "set title \" Trajectory with Drag \ ""); gnuplot_cmd (к, "Участок \" Flight_Path.dat \»с использованием 1: 2 название \ "Путь полета \" с линиями, \ сна (7); gnuplot_close (к); возврат 0;} – JMzance

2

Хотя я видел много способов сделать это, самый простой способ сделать это было бы с помощью системы() (из stdlib.h) функция в С. Сначала сделайте GNUPLOT сценарий и сохранить его как «имя.gp» (ни имя, ни расширение).
Простой скрипт будет,

plot 'Output.dat' with lines 

После сохранения этого файла сценария, просто добавьте
system("gnuplot -p 'name.gp'");
в конце кода.
Это так просто.

0

Я адаптировал принятый ответ для построения массива с плавающей точкой, избегая при этом использования временного файла. В нем float* data_ - это массив и size_t size_ его размер. Надеюсь, это полезно для кого-то!

Приветствия,
Andres

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"); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^