使C代码自动绘制图形

时间:2010-08-19 11:18:56

标签: c gnuplot numerical-methods piping

我编写了一个程序,它将数据列表写入'.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代码更改)。非常感谢。

5 个答案:

答案 0 :(得分:37)

我在搜索关于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”来避免写入文件。

e.g。

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

答案 1 :(得分:5)

您可以创建一个gnuplot脚本并生成一个运行gnuplot的进程来从命令行绘制此脚本,或者您可以使用其中一个提供的接口。对于C,Nicolas Devillard提供了一个基于POSIX管道的接口: http://ndevilla.free.fr/gnuplot/ ...并且可以通过git获得基于iostream的C ++版本(参见:http://www.stahlke.org/dan/gnuplot-iostream/

尽管如此,最便携且可能最简单的方法仍然是调用gnuplot来绘制脚本。正如sje397所提到的,请检查文档中是否有stdlib.h中的system()调用。

在旁注中,还有GNU plotutils,它提供了libplot,一个用于绘制数据集的库,您可以在应用程序中使用它。请参阅:http://www.gnu.org/software/plotutils/

答案 2 :(得分:2)

虽然我已经看到了很多这样做的方法,但最简单的方法是使用C中的system()(来自stdlib.h)函数。 首先制作一个gnuplot脚本并将其保存为&#34; name.gp&#34; (名称和扩展名都不重要) 一个简单的脚本就是,

plot 'Output.dat' with lines

保存此脚本文件后,只需添加
system("gnuplot -p 'name.gp'");
在代码的最后。
它就这么简单。

答案 3 :(得分:0)

我已经调整了接受的答案来绘制浮点数组,同时避免使用临时文件。其中,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");
}

答案 4 :(得分:0)

我知道为时已晚,但请回答是否有帮助。 fputs确实可以完成您的工作。首先,您需要在临时文件data.temp中打印要绘制的数据。

FILE *pipe_gp = popen("gnuplot -p", "w");
fputs("set terminal png \n",pipe_gp);
fputs("set output 'abc.png' \n",pipe_gp);
fputs("set xlabel 'f' \n",pipe_gp);
fputs("set xrange [0:100] \n",pipe_gp);
fputs("set yrange [0:100] \n",pipe_gp);
fputs("plot 'data.temp' u 1:2 w circles lc rgb 'pink' notitle \n",pipe_gp);
pclose(pipe_gp);