现在的位置: 首页 > 综合 > 正文

C++ 结合 gnuplot 实现数据可视化

2018年10月28日 ⁄ 综合 ⁄ 共 2365字 ⁄ 字号 评论关闭

C++ 结合 gnuplot  实现数据可视化

之前做课题时,使用的是C++结合OpenCV编程实现,过程中想要对一组数据作图表的可视化,但是C++和OpenCV中都没有提供相应的图表可视化接口,当时是自己利用OpenCV写了一个粗糙的曲线显示函数,但总觉不方便。今天想着来解决这个问题,在网上搜索,找到了gnuplot以及gnuplot在C++中调用的一个函数库:

A. 这个gnuplot库的链接是:http://www.deuxmille.org/archives/1529 (可能需要代理)

B. 同时这篇文章对程序调试也给了很大的启示:https://gist.github.com/zhaojkun/5895566


gnuplot 是一个通用、强大的科学绘图软件,可以跨平台调用,之前自己用SVM的时候有接触过一点(优化参数选取的时候,库函数调用了gnuplot来可视化显示参数的影响)。

利用上述 gnuplot 库的链接得到压缩包GNUPlot1.zip。另外需要到官网去下载 gnuplot 软件。


解压GNUPlot1.zip后会得到一个VC06的工程文件,个人用VS2008打开、重新编译。

若直接运行该工程,会得到如下结果:


因为该库需要提供gnuplot的可执行文件,但是直接按A 链接所说的,拷贝gnuplot的bin文件中的pgnuplot.exe到该工程目录,仍旧不能解决问题。

根据B链接的提示,调试代码,发现Gnuplot这个类有个关键的init函数:

void Gnuplot::init()
{
    m_sGNUPlotFileName = "pgnuplot.exe";
    if (!this->get_program_path(m_sGNUPlotFileName))
    {
        this->valid = false;
        throw GnuplotException("Can't find gnuplot in your PATH");
    }
    
    this->gnucmd = _popen(m_sGNUPlotFileName.c_str(),"w");
    if (!this->gnucmd)
    {
        this->valid = false;
        throw GnuplotException("Couldn't open connection to gnuplot");
    }
    this->nplots = 0;
    this->valid = true;
}

其中第一个if 处是对pgnuplot.exe文件是否存在的检查,进入该函数,发现

bool Gnuplot::get_program_path(const string pname)
{
    list<string> ls;
    char *path;

    path = getenv("PATH");
    if (!path)
      {
        cerr << "Path is not set" << endl;
        return false;
      }
    else
      {
#ifdef WIN32
        stringtok(ls,path,";");
#else
        stringtok(ls,path,":");
#endif
        for (list<string>::const_iterator i = ls.begin();
                i != ls.end(); ++i)
          {
            string tmp = (*i) + "/" + pname;
#ifdef WIN32
            if (_access(tmp.c_str(),0) == 0)
#else
            if (access(tmp.c_str(),X_OK) == 0)
#endif
                return true;
          }
      }
    return false;
}

path = getenv("path")代码处指示,其对pgnuplot.exe文件做检查时,依据的是环境变量(env) ‘path’ ,所以只要将环境变量‘path’ 中加入gnuplot软件所在的路径:

本人使用:D:\Program Files\Gnuplot\gnuplot\bin,这个路径要一直指到pgnuplot.exe 所在文件。


而后重新编译工程,应该就能够直接运行了,运行结果如下:


该库提供的demo中有直线、函数、用户自定义数据等数据的曲线显示,并提供了一些简单的图形设置接口。若用户有需要,可以在熟悉了gnuplot的编程命令后,自行扩展该库。如此,就能在C++中调用gnuplot实现数据的图表可视化了。

备注:设置环境变量的方法的一个缺点就是需要 ‘安装’,不能‘脱机’。因为要在不同电脑上使用的话,必须设置环境变量,添加路径。如果不想这样,一个最笨的办法是:

1、屏蔽第一个if 段检测代码

void Gnuplot::init()
{
    m_sGNUPlotFileName = "pgnuplot.exe";
    //if (!this->get_program_path(m_sGNUPlotFileName))
    //{
    //    this->valid = false;
    //    throw GnuplotException("Can't find gnuplot in your PATH");
    //}
    
    this->gnucmd = _popen(m_sGNUPlotFileName.c_str(),"w");
    if (!this->gnucmd)
    {
        this->valid = false;
        throw GnuplotException("Couldn't open connection to gnuplot");
    }
    this->nplots = 0;
    this->valid = true;
}

2、将gnuplot文件bin中的所有文件拷贝到工程文件中(这样gnuplot就跟着工程文件走了,不用管电脑配置问题),然后就可以直接运行了。

(直接将bin文件拷过来,在现有代码下是不行的,但其实这样是更好的处理方式,以免gnuplot的文件和工程文件混淆。若路过的各位能提供修改代码的方式,在工程下用一个bin文件管理gnuplot的文件,希望指教。)



抱歉!评论已关闭.