Создание кода на C для автоматического построения графика - PullRequest
16 голосов
/ 19 августа 2010

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

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

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

Ответы [ 4 ]

37 голосов
/ 04 августа 2011

Я сталкивался с этим, когда искал что-то еще относительно gnuplot. Хотя это старый вопрос, я решил добавить пример кода. Я использую это для моей программы, и я думаю, что она делает довольно аккуратную работу. AFAIK, эта ТРУБА работает только в системах 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.

РЕДАКТИРОВАТЬ 2

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

* * 1 022, например,
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");
5 голосов
/ 19 августа 2010

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

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

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

2 голосов
/ 03 сентября 2015

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

plot 'Output.dat' with lines

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

0 голосов
/ 06 декабря 2017

Я адаптировал принятый ответ для построения массива с плавающей точкой, избегая использования временного файла.В нем 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");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...