前言
gnuplot是一个可在多种操作系统中(Linux、Windows、Mac OS x等)使用的开源画图软件,支持2D、3D画图,也支持多种形式的输出如交互式的屏幕终端显示和fig/jpeg/png/pdf/…多种格式文件等,同时它的命令格式也不复杂,上手难度不大。
事实上gnuplot与matlab、python的画图功能大同小异,但是因为gnuplot相对轻便很多,使用C/C++程序调用以实现数据可视化的运行速度很快,而且无需保存中间数据文件后再使用其他软件读入并画图。
gnuplot的官网地址为http://www.gnuplot.info/,可以进行下载并查看用户手册、demo等。
一、gnuplot安装
gnuplot的当前版本是2020年12月发布的Version 5.4 Patchlevel 1,源码及安装包可以在https://sourceforge.net/projects/gnuplot/files/gnuplot/5.4.1/中下载,其中"gp541-win64-mingw.exe"可执行文件可以在64位Windows上实现简易安装。
下载完成后打开安装文件按步骤操作即可,只需注意在"Select Additional Tasks"页面中勾选"Add application directory to your PATH environment variable"
选项,即将gnuplot的安装文件夹目录添加至系统环境变量中以便在VS中调用。
二、安装验证
为了验证环境变量设置成功,可以在cmd中输入gnuplot,如果能够进入gnuplot console,则说明PATH设置成功;也可以简单地输入"plot sin(x)"测试一下gnuplot是否能够正常使用。
三、C/C++调用方式
其实在VS工程C/C++程序调用gnuplot的原理非常简单,就是使用I/O流操作,先调用_popen()函数创建一个管道,将画图命令通过这个管道传输至gnuplot,即可实现调用gnuplot画图,画图完成之后使用_pclose()函数关闭此管道即可。
刚开始上手的写gnuplot的命令时可能会觉得有点难,可以下载John Edwards写好的C/C++接口进行调用:https://sourceforge.net/projects/gnuplotc/。但是为了画出自己想要的图,最好还是花点时间摸索,根据自己的需求去查阅官方的用户手册。
C/C++调用gnuplot的程序如下:
#include <stdio.h> /* _popen()函数所在头文件 */
FILE* pipe = _popen("gnuplot", "w"); /* 以可写方式打开gnuplot终端,如果pipe为空则说明打开失败,可能是因为未将gnuplot设置在PATH环境变量中 */
fprintf(pipe, "plot sin(x)\n"); /* 将gnuplot的画图命令输出到管道中,命令需要以换行符结束 */
fprintf(pipe, "pause mouse\n"); /* 使用此命令可以让画图窗口停留,作用为等待用户点击鼠标后关闭窗口 */
_pclose(pipe); /* 关闭pipe管道,gnuplot退出 */
四、Demo
使用gnuplot官方提供的一个三维画图demo程序world2.dem实现在VS2019中的画图显示:
#include <stdio.h>
void main()
{
FILE* pipe = _popen("gnuplot", "w");
if (pipe == NULL)
{
exit(-1);
}
fprintf(pipe, "set terminal wxt size 600, 400\n");
fprintf(pipe, "unset border\n");
fprintf(pipe, "set dummy u, v\n");
fprintf(pipe, "set angles degrees\n");
fprintf(pipe, "set parametric\n");
fprintf(pipe, "set view 60, 136, 1.22, 1.26\n");
fprintf(pipe, "set samples 64, 64\n");
fprintf(pipe, "set isosamples 13, 13\n");
fprintf(pipe, "set mapping spherical\n");
fprintf(pipe, "set style data lines\n");
fprintf(pipe, "unset xtics\n");
fprintf(pipe, "unset ytics\n");
fprintf(pipe, "unset ztics\n");
fprintf(pipe, "set title 'Labels colored by GeV plotted in spherical coordinate system'\n");
fprintf(pipe, "set urange [ -90.0000 : 90.0000 ] noreverse nowriteback\n");
fprintf(pipe, "set vrange [ 0.00000 : 360.000 ] noreverse nowriteback\n");
fprintf(pipe, "set xrange [ * : * ] noreverse writeback\n");
fprintf(pipe, "set x2range [ * : * ] noreverse writeback\n");
fprintf(pipe, "set yrange [ * : * ] noreverse writeback\n");
fprintf(pipe, "set y2range [ * : * ] noreverse writeback\n");
fprintf(pipe, "set zrange [ * : * ] noreverse writeback\n");
fprintf(pipe, "set cblabel 'GeV'\n");
fprintf(pipe, "set cbrange [ 0.00000 : 8.00000 ] noreverse nowriteback\n");
fprintf(pipe, "set rrange [ * : * ] noreverse writeback\n");
fprintf(pipe, "set colorbox user\n");
fprintf(pipe, "set colorbox vertical origin screen 0.9, 0.2 size screen 0.02, 0.75 front noinvert bdefault\n");
fprintf(pipe, "NO_ANIMATION = 1\n");
fprintf(pipe, "splot cos(u)*cos(v),cos(u)*sin(v),sin(u) notitle with lines lt 5, 'world.dat' notitle with lines lt 2, 'srl.dat' using 3:2:(1):1:4 with labels notitle point pt 6 lw .1 left offset 1,0 font ',7' tc pal\n");
fprintf(pipe, "pause mouse\n");
_pclose(pipe);
}
最终显示如下图: