【问题标题】:How to plot data by c program?如何通过c程序绘制数据?
【发布时间】:2012-12-28 00:16:12
【问题描述】:

我是一名机械工程师,在 C 编程方面的知识有限。我写了一些代码来进行模拟,我想可视化模拟结果。目前我正在使用Dev-C 来编写我的代码。使用fopenfprintf 命令,我生成了一个包含结果的.dat 文件。然后我打开GNUPLOT 程序并导入我的.dat 文件以绘制结果。这需要时间,我必须等到模拟结束。有没有一种简单的方法可以将我的绘图仪与Dev-C 连接起来,以便我的绘图仪在模拟过程中开始绘制数据?任何图书馆等?

【问题讨论】:

  • 如果没有完成模拟,你有数据要绘制吗?
  • 究竟什么需要时间?手动执行gnuplot 并导入数据?或者gnuplot 本身是否需要花费大量时间来绘制它?如果它是第一个,您可以通过从模拟器本身执行gnuplot 轻松摆脱它。例如在 POSIX-likes 中,有 exec function
  • 我想知道您是否不能使用管道代替文件。
  • 据我所知,像 gnuplot 和 mathGL 这样流行的绘图库需要在绘图前准备好所有数据。
  • 大家好,感谢您的回复。我会提供快速信息。需要时间的是每次手动编写 gnuplot 命令。通过我在 C 程序中编写的一些命令,我​​希望 gnuplot 自动绘制我的数据。因为它很难,所以无论是在模拟过程中还是模拟结束都不是很重要......因为我在这里阅读了其他内容,所以我正在研究“_popen”命令。但不知何故,程序说:“popen undeclared (first use in this function)”。 (我使用的是win7,我添加了#include )有什么想法吗?

标签: c graph plot gnuplot simulation


【解决方案1】:

既然您已经了解 gnuplot,那么最简单的做法可能就是从您的程序中调用 gnuplot 并将数据通过管道传递给它:

FILE *gnuplot = popen("gnuplot", "w");
fprintf(gnuplot, "plot '-'\n");
for (i = 0; i < count; i++)
    fprintf(gnuplot, "%g %g\n", x[i], y[i]);
fprintf(gnuplot, "e\n");
fflush(gnuplot);

【讨论】:

  • 我在 unix 环境和在 windows 上使用 cygwin 时使用过这个。它总是对我有用:)。
  • @Edgar 嗨,埃德加,感谢您的回答。从我的程序中调用 gnuplot 并将数据传送给它正是我想要做的。我将您的代码添加到我的程序中(当然我也更改了 X[i] 和 y[i])。但是我得到了这个编译错误:“'popen' undecleared(第一次在这个函数中使用)。我使用的是 Win 7,你知道为什么会出现这个错误吗?谢谢。
  • 由于 popen() 是 POSIX,在 Windows 上您可以尝试使用下划线:_popen()。
  • @Edgar,这也行不通。您编写的代码似乎是实现我目标的最简单方法,但我无法编译它:)
  • set nokey; 添加到绘图前可以消除烦人的图例。
【解决方案2】:

好的,当您写入文件时,一种解决方案是在写入文件时调用 system(),然后调用 gnuplot。

但是,这意味着您应该每次都更改文件名,但我担心如果您这样做,它看起来会不正确,因为您每次都发送少量数据。

http://www.gnu.org/software/libc/manual/html_node/System-Calls.html

我从未使用过 gnuplot,但如果您查看此页面 (http://gnuplot-tricks.blogspot.com/),您可能会发现一些可以使其正常工作的技巧。

但是,我认为,除非您要自己绘制所有内容并跳过 gnuplot,否则您可能只需要等待。

您可能会发现 gnuplot 的 C 接口可能对您有所帮助:

http://ndevilla.free.fr/gnuplot/

【讨论】:

    【解决方案3】:

    我一直在使用PLPlot 从 C 中绘图,发现它既有效又简单。它是跨平台的、开源的,并支持丰富的绘图功能。我建议您查看示例以开始使用。

    【讨论】:

      【解决方案4】:

      pbPlots 非常易于使用,适用于所有 C 编译器。

      github page 下载 pbPlots.c/h 和 supportLib.c/h 并将它们包含在您的构建中。

      这是一个完整的示例,它将在 PNG 文件中生成绘图。

      #include "pbPlots.h"
      #include "supportLib.h"
      
      int main(){
      
          double x [] = {-1, 0, 1, 2, 3, 4, 5, 6};
          double y [] = {-5, -4, -3, -2, 1, 0, 1, 2};
      
          RGBABitmapImageReference *imageRef = CreateRGBABitmapImageReference();
      
          DrawScatterPlot(imageRef, 600, 400, x, 8, y, 8);
      
          size_t length;
          double *pngData = ConvertToPNG(&length, imageRef->image);
          WriteToFile(pngData, length, "plot.png");
      
          return 0;
       }
      

      还有很多可用的选项,这些都在 github 页面上进行了描述。

      【讨论】:

      • 我将 pbPlots.c/h 和 supportLib.c/h 文件添加到 CLion 项目中,但是当我尝试运行您的示例时出现错误:C:/Users/flori/CLionProjects/Plottest /main.c:9:对“CreateRGBABitmapImageReference”的未定义引用(+ 更多未解决的引用)......我做错了什么?
      • @le_lemon,您是否在构建中包含了 pbPlots.c 和 supportLib.c?在 C 中,编译器使用 .h 文件,而链接器使用 .c 文件。链接器需要知道包含了哪些 C 文件。错误来自链接器未获取已编译的 .c 文件。
      • @MartinJohansen 你是作者吗?
      • @ChefGladiator,是的,我是作者。
      【解决方案5】:

      我环顾四周看看其他人在 gnuplot 中的实时绘图方面做了什么,发现了这个:

      http://users.softlab.ntua.gr/~ttsiod/gnuplotStreaming.html

      有一个小的 Perl 脚本可以驱动绘图,您只需将信息通过管道输入即可。

      由于您的数据正在写入文件,您可能需要tail -f yourdata.dat 并将其通过管道传输到实时绘图仪中。

      另外,因为您使用的是 stdio 文件调用,所以您需要定期刷新(通过调用 fflush

      很明显,您的模拟将在后台或另一个 shell 中运行。这样您就可以随时退出绘图而不会中断模拟。

      希望对你有用。

      【讨论】:

      • 嗨,帕迪,感谢您的回答。我检查了你链接的网页。实际上,我在一家公司工作期间正在使用这种方法(准备 make 文件、bash 文件)。我们在这里使用的是 Linux,程序都是由 IT 设置的。现在在我的个人电脑上我使用的是 Windows,所以这次我需要为 windows 平台学习所有东西(知识贫乏)。有没有办法在 Windows 中做这些事情?
      • 最有希望的方法是安装 Cygwin,但您可能会在安装 Perl for Windows 时有所突破。有一个移植版本正在运行。如果你能坚持使用你知道的工具和方法,而不是学习一个全新的(在 Windows 的情况下是残废的)工具集,那就太好了。
      【解决方案6】:

      有一个名为 DISLIN 的广泛图书馆用于科学目的。甚至在 Fortran 语言中也可用。

      您可以在官网查看示例。

      您可以在DISLIN Homepage免费获取

      【讨论】:

      • 请解释这与问题的关系以及它是如何工作的。
      • @m-chen-3 您可以在Dislin examples 找到一组示例。只需单击情节教程之一,然后选择您的语言 (C)。
      猜你喜欢
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-19
      • 2021-04-01
      • 2016-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多