Loading... ### 一、前言 在写代码的过程中,我们有时候需要对数据进行可视化,但是对于C++来说,并没有一个像python中matplotlib一样方便使用且功能强大的绘图包。但是,我在github发现了一个名为`matplotlib-cpp`的绘图开源包,第一眼看到我以为这可能时matplotlib的C++版本,但后来仔细一看是C++调用python。将matplotlib进行了封装。但是,这对一般的数据可视化来说并不是大问题,即便运行速度会降低。 [matplotlib-cpp项目地址](https://github.com/lava/matplotlib-cpp) ### 二、使用 首先,克隆项目之后,我们来看看代码的目录结构 - contrib - examples - matplotlibcpp.h - ....(not important) `contrib`目录下有作者提供的编译方法。 `examples`目录下有一些代码示例。 `matplotlibcpp.h`只需要在代码中包含这个头文件就可以使用matplotlibcpp提供的API画图。 对于我来说,我平常使用windows10+ubuntu16.04的开发环境,因此最简单的方法就是使用cmake来构建项目。以下代码为contrib/CMakeLists.txt提供的示例。 ```cmake cmake_minimum_required(VERSION 3.7) project (MatplotlibCPP_Test) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) include_directories(${PYTHONHOME}/include) include_directories(${PYTHONHOME}/Lib/site-packages/numpy/core/include) link_directories(${PYTHONHOME}/libs) add_definitions(-DMATPLOTLIBCPP_PYTHON_HEADER=Python.h) add_executable(minimal ${CMAKE_CURRENT_SOURCE_DIR}/../examples/minimal.cpp) add_executable(basic ${CMAKE_CURRENT_SOURCE_DIR}/../examples/basic.cpp) add_executable(modern ${CMAKE_CURRENT_SOURCE_DIR}/../examples/modern.cpp) add_executable(animation ${CMAKE_CURRENT_SOURCE_DIR}/../examples/animation.cpp) add_executable(nonblock ${CMAKE_CURRENT_SOURCE_DIR}/../examples/nonblock.cpp) add_executable(xkcd ${CMAKE_CURRENT_SOURCE_DIR}/../examples/xkcd.cpp) add_executable(bar ${CMAKE_CURRENT_SOURCE_DIR}/../examples/bar.cpp) ``` 需要注意`PYTHONHOME`这个变量,在ubuntu和windows10上,这个变量应该设置为你本地的python根目录。 在windows10下,需要使用`set`命令,将`PYTHONHOME`变量值设置为你python的安装目录。 ```cmake set(PYTHONHOME C:/Users/%username%/AppData/Local/Programs/Python/Python36) ``` 在ubuntu下, ```cmake find_package(PythonLibs 2.7) target_include_directories(yourproject PRIVATE ${PYTHON_INCLUDE_DIRS}) target_link_libraries(yourproject ${PYTHON_LIBRARIES}) ``` **下面是我改的CMakeLists.txt,作为参考** ```cmake cmake_minimum_required(VERSION 3.5) project (matplitlib_cpp_test) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) IF (WIN32) MESSAGE(STATUS "Now is windows") # 改为你的python路径 set(PYTHONHOME C:/Users/%username%/AppData/Local/Programs/Python/Python36) add_executable(simple_test src/simple_test.cpp) include_directories(${PYTHONHOME}/include) include_directories(${PYTHONHOME}/Lib/site-packages/numpy/core/include) link_directories(${PYTHONHOME}/libs) ELSEIF (UNIX) MESSAGE(STATUS "Now is UNIX-like OS's.") find_package(PythonLibs 2.7) add_executable(simple_test src/simple_test.cpp) target_include_directories(simple_test PRIVATE ${PYTHON_INCLUDE_DIRS}) target_link_libraries(simple_test ${PYTHON_LIBRARIES}) include_directories(/usr/local/lib/python2.7/dist-packages/numpy/core/include) ENDIF () include_directories(include) add_definitions(-DMATPLOTLIBCPP_PYTHON_HEADER=Python.h) ``` 另外,你也可以直接访问我的github项目,我会将我的测试示例放在上面:[matplotlibcpp-test](https://github.com/Kevinnan-teen/My-Interesting-projects-collection/blob/master/code_test/matplitlib_cpp_test/) 编写完CMakeLists.txt之后,怎么编译呢?很简单,新建在CMakeLists.txt当前目录下新建一个名为`build`的目录,然后使用命令`cmake ..`,即可编译。 在win10下,默认生成Visual studio项目,你直接打开.sln文件编译运行即可。需要注意的是,在按下绿色三角编译运行之前,你需要看你的python是不是支持Debug,即安装python时有没有安装Debug模块,可以在你的python路径下的libs文件夹内看是否有pythonxx_d.lib 类似文件。如果你没有安装Debug功能,那么需要在Visual studio将Debug模式改为Release模式再编译。其次,你需要看你安装的python版本是32位还是64位的,同样,如果是64位,Visual studio默认生成64位的可执行文件不用修改,但是如果你的python是32位,那么需要将Visual studio生成可执行文件的配置改为32位。最后,如果编译报错`不能打开pythonxx.lib文件`,那么你需要将python路径下libs文件夹下的pythonxx.lib复制到build目录下,然后再编译。如果还遇到其他问题,就自行google吧。 在ubuntu下,cmake之后会生成Makefile文件,使用`make`命令进行编译即可。 ### 三、测试结果 #### 3.1 简单曲线 ```cpp #include "matplotlibcpp.h" namespace plt = matplotlibcpp; int main() { plt::plot({1,3,2,4}); plt::show(); } ```  #### 3.3 动态曲线 ```cpp #define _USE_MATH_DEFINES #include <cmath> #include "matplotlibcpp.h" namespace plt = matplotlibcpp; int main() { int n = 1000; std::vector<double> x, y, z; for(int i=0; i<n; i++) { x.push_back(i*i); y.push_back(sin(2*M_PI*i/360.0)); z.push_back(log(i)); if (i % 10 == 0) { // Clear previous plot plt::clf(); // Plot line from given x and y data. Color is selected automatically. plt::plot(x, y); // Plot a line whose name will show up as "log(x)" in the legend. plt::named_plot("log(x)", x, z); // Set x-axis to interval [0,1000000] plt::xlim(0, n*n); // Add graph title plt::title("Sample figure"); // Enable legend. plt::legend(); // Display plot continuously plt::pause(0.01); plt::save("./dynamic_curve.png"); } } } ```  更多示例可以访问该github项目。 ### 四、参考资料 [1] [matplotlib-cpp](https://github.com/lava/matplotlib-cpp) [2] [C++调用matplotlib](https://mangoroom.cn/cpp/call-matplotlib-on-cpp.html) Last modification:January 20th, 2021 at 05:53 pm © 允许规范转载