Создание C-графика на графике автоматически
Я написал программу, которая записывает список данных в файл ".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-кода). Большое спасибо.
Ответы
Ответ 1
Я столкнулся с этим, когда искал что-то еще в отношении 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;
}
ИЗМЕНИТЬ
В моем приложении я также столкнулся с проблемой, что график не появляется, пока вызывающая программа не будет закрыта. Чтобы обойти это, добавьте fflush(gnuplotPipe)
после того, как вы использовали fprintf
, чтобы отправить его окончательную команду.
Я также видел, что пользователи Windows могут использовать _popen
вместо popen
- однако я не могу подтвердить это, поскольку у меня нет установленной Windows.
РЕДАКТИРОВАТЬ 2
Можно избежать записи в файл, отправив gnuplot команду plot '-'
, за которой следуют точки данных, за которыми следует буква "e".
например.
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");
Ответ 2
Вы можете создать gnuplot script и запустить процесс, запускающий gnuplot, для построения этого script из командной строки, или вы можете использовать один из предоставленных интерфейсов. Для C существует интерфейс POSIX на основе труб от Nicolas Devillard, доступный здесь:
http://ndevilla.free.fr/gnuplot/
... и версия на С++ на iostream доступна через git (см. http://www.stahlke.org/dan/gnuplot-iostream/)
Самый портативный и, вероятно, самый простой способ, по-прежнему будет называть gnuplot для построения script. Как упоминалось в sje397, проверьте свою документацию на вызов system() в stdlib.h.
В боковом поле есть также GNU plotutils, который предлагает libplot, библиотеку для построения наборов данных, которую вы можете использовать в своем приложении. См.: http://www.gnu.org/software/plotutils/
Ответ 3
Хотя я видел много способов сделать это, самым простым способом сделать это будет использование функции system() (из stdlib.h) в C.
Сначала создайте gnuplot script и сохраните его как "имя .gp" (ни имя, ни расширение).
Простым script будет,
plot 'Output.dat' with lines
После сохранения этого script файла просто добавьте
system("gnuplot -p 'name.gp'");
в конце вашего кода.
Это так просто.
Ответ 4
Я адаптировал принятый ответ для построения массива float, избегая при этом использования временного файла. В нем float* data_
- массив и size_t size_
его размер. Надеюсь, это полезно для кого-то!
Cheers,
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");
}