C语言 使 C 代码自动绘制图形

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3521209/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:13:33  来源:igfitidea点击:

Making C code plot a graph automatically

cgnuplotnumerical-methodspiping

提问by JMzance

I have written a program which writes a list of data to a '.dat' file with the intention of then plotting it separately using gnuplot. Is there a way of making my code plot it automatically? My output is of the form:

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

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

Ideally, when I run the code the graph would also be printed with an x-label, y-label and title (which could be changed from my C code). Many thanks.

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

回答by BenB

I came across this while searching for something else regarding gnuplot. Even though it's an old question, I thought I'd contribute some sample code. I use this for a program of mine, and I think it does a pretty tidy job. AFAIK, this PIPEing only works on Unix systems (see the edit below for Windows users). My gnuplot installation is the default install from the Ubuntu repository.

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

EDIT

编辑

In my application, I also ran into the problem that the plot doesn't appear until the calling program is closed. To get around this, add a fflush(gnuplotPipe)after you've used fprintfto send it your final command.

在我的应用程序中,我还遇到了在调用程序关闭之前绘图不会出现的问题。为了解决这个问题,fflush(gnuplotPipe)在你用来fprintf发送你的最终命令之后添加一个。

I've also seen that Windows users may use _popenin place of popen-- however I can't confirm this as I don't have Windows installed.

我还看到 Windows 用户可能会使用_popen代替popen- 但是我无法确认这一点,因为我没有安装 Windows。

EDIT 2

编辑 2

One can avoid having to write to a file by sending gnuplot the plot '-'command followed by data points followed by the letter "e".

可以通过向 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");

回答by Jim Brissom

You can either create a gnuplot script and spawn a process running gnuplot to plot this script from the commandline, or you may use one of the provided interfaces. For C, there is a POSIX pipe-based interface from Nicolas Devillard available here: http://ndevilla.free.fr/gnuplot/...and an iostream-based C++ version is available via git (see: http://www.stahlke.org/dan/gnuplot-iostream/)

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

The most portable and probably the easiest way would still be calling gnuplot to plot a script, though. As sje397 mentioned, check your documentation for the system() call in stdlib.h.

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

On a sidenote, there is also GNU plotutils, which offers libplot, a library for plotting datasets, which you could use in your application. See: http://www.gnu.org/software/plotutils/

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

回答by Nidish Narayanaa

Although I've seen a lot of ways of doing this, the most simplest way of doing this would be by using the system() (from stdlib.h) function in C. First make a gnuplot script and save it as "name.gp" (neither the name nor the extension matter).
A simple script would be,

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

plot 'Output.dat' with lines

After saving this script file, just add
system("gnuplot -p name.gp");
at the end of your code.
It's as simple as that.

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

Make sure to add gnuplot path to the Windows System Path variables.

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

回答by fr_andres

I've adapted the accepted answer to plot a float array while avoiding the use of a temporary file. In it, float* data_is the array and size_t size_its size. Hopefully it is helpful for someone!

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