让C代码自动绘制图表

发布于 2024-09-14 21:15:34 字数 360 浏览 12 评论 0原文

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

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:

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

装迷糊 2024-09-21 21:15:34

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

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.

#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 fprintf to send it your final command.

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

EDIT 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".

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");
一生独一 2024-09-21 21:15:34

您可以创建一个 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() 调用的文档。

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

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/ )

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.

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/

べ繥欢鉨o。 2024-09-21 21:15:34

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

plot 'Output.dat' with lines

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

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

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,

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.

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

热风软妹 2024-09-21 21:15:34

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

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!

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");
}
信愁 2024-09-21 21:15:34

我知道为时已晚,但回答是否可以帮助某人。
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);

I know it's too late, but answering if it may help someone.
fputs really does the job, you want. first you need to print the data you want to plot in a temporary file 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文