代码之家  ›  专栏  ›  技术社区  ›  JMzance

使C代码自动绘制图形

  •  16
  • JMzance  · 技术社区  · 14 年前

    我已经编写了一个程序,它将一个数据列表写入一个“.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 回复  |  直到 7 年前
        1
  •  35
  •   BenB    10 年前

    我在寻找关于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;
    }
    

    编辑

    在我的应用程序中,我也遇到了这样一个问题:在调用程序关闭之前,图不会出现。要绕过此问题,请添加 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
  •  5
  •   Jim Brissom    14 年前

    您可以创建一个gnuplot脚本并生成一个运行gnuplot以从命令行绘制此脚本的进程,也可以使用提供的接口之一。对于C,这里有一个来自Nicolas Devillard的基于POSIX管道的接口: http://ndevilla.free.fr/gnuplot/ 基于Git的基于IoSt流的C++版本可用(参见: http://www.stahlke.org/dan/gnuplot-iostream/ )

    不过,最可移植和最简单的方法仍然是调用gnuplot来绘制脚本。如sje397所述,在stdlib.h中检查system()调用的文档。

    另一方面,还有GNU Plottutils,它提供了libplot,一个用于绘制数据集的库,可以在应用程序中使用。见: http://www.gnu.org/software/plotutils/

        3
  •  2
  •   Nidish Narayanaa    9 年前

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

    plot 'Output.dat' with lines
    

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

        4
  •  0
  •   fr_andres    7 年前

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