【问题标题】:Making C code plot a graph automatically使 C 代码自动绘制图形
【发布时间】:2011-04-01 01:49:34
【问题描述】:

我编写了一个程序,它将数据列表写入“.dat”文件,然后使用 gnuplot 单独绘制它。有没有办法让我的代码自动绘制它?我的输出格式为:

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

理想情况下,当我运行代码时,图形也会打印一个 x-label、y-label 和标题(可以从我的 C 代码中更改)。非常感谢。

【问题讨论】:

  • 也许可以查看system 函数。

标签: c gnuplot numerical-methods piping


【解决方案1】:

您可以创建一个 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/

【讨论】:

  • 我并不擅长理解所有这些文档内容,但我找到了 system() 的声明: int system(const char *command);那么是否只是添加类似这样的内容?:system(gnuplot plot "data_set.dat" with 1:2 using lines);
  • 最后我选择了这样的东西:
  • #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, "设置标题\"拖动轨迹\""); gnuplot_cmd(k, "plot \"Flight_Path.dat\" using 1:2 title \"Flight Path\" with lines, \ sleep(7); gnuplot_close(k); return 0; }
  • 我确定您丢失了该代码的某些部分,即您在之后立即打开和关闭文件。此外,在 cmets 中格式化也很糟糕。请编辑您的原始帖子并添加代码 - 我自己会这样做,但正如我所说,我相信您的代码缺少一些东西。
【解决方案2】:

我在搜索有关 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;
}

编辑

在我的应用程序中,我还遇到了直到调用程序关闭后才会出现绘图的问题。要解决此问题,请在使用 fprintf 后添加 fflush(gnuplotPipe) 以向其发送最终命令。

我还看到 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");

【讨论】:

  • 我知道自发布此答案以来已经很长时间了,但我使用了您第二次编辑中的代码以及其中带有 commandsForGnuplot 的 for 循环来添加命令,并绘制但它不添加任何命令(标题、xlabel 或 ylabel)。如果不是这样,我该如何添加它们?请。
【解决方案3】:

虽然我见过很多方法,但最简单的方法是使用 C 中的 system()(来自 stdlib.h)函数。 首先制作一个 gnuplot 脚本并将其保存为“name.gp”(名称和扩展名都无关紧要)。
一个简单的脚本是,

plot 'Output.dat' with lines

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

确保将 gnuplot 路径添加到 Windows 系统路径变量。

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      我知道为时已晚,但如果它可能对某人有帮助,请回答。 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);
      

      【讨论】:

        猜你喜欢
        • 2011-09-21
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多