c++ - 使用 Python 的 Matplotlib 绘制在 C++ 程序中生成的数据

标签 c++ python-3.x matplotlib fork

我目前正在使用 Qt 开发 C++ 应用程序,我必须绘制一些由 C++ 生成的数据( vector 场、时间信号相关矩阵等...)。我发现来自 Python 的 Matplotlib 非常好,这就是为什么我想将数据从 C++ 程序传递到将进行绘图的 Python 函数。问题是对 Python 函数的调用正在阻塞,例如它会停止 Qt GUI。我目前通过 fork 一个新进程并从子进程调用 Python 函数来解决这个问题。

我的问题是,是否有更有效的方法从 C++ 打开 Python Plot,或者如果 fork 一个新进程几乎是我所能做的?

调用 Python-Plotting-Function 的 C-Test 程序:

#include <python3.6/Python.h>
#include <python3.6/listobject.h>
#include <stdlib.h>
#include <fstream>
#include <unistd.h>
#include <math.h>

#define N_LIST 100

using namespace std;

//define some constants for plotting sin(2*pi*50*t)
double f=50;
double ang_frequency=2*M_PI*f;
double dt=1/(f*N_LIST);

int main(int argc,char** argv){
    //set the PYTHONPATH variable to that python can find the Python script containing the plotting function
    char currentdir[200];
    getcwd(currentdir,200);
    printf("%s\n",currentdir);
    if(setenv("PYTHONPATH",currentdir,0)!=0){
        printf("Could not set PYTHONPATH\n");
    };
    //start the python interpreter
    Py_Initialize();
    //load the python module
    PyObject* modulename=PyUnicode_FromString("Module");
    PyObject* module=PyImport_Import(modulename);
    Py_DECREF(modulename);
    if(module!=NULL){
        //load the python function which should do the plotting
        PyObject* py_function=PyObject_GetAttrString(module,"plotFunction");
        //create two python lists for holding the time points and signal points
        PyObject* py_listy=PyList_New(N_LIST);
        PyObject* py_listx=PyList_New(N_LIST);
        //fill the lists with values
        for(int i=0; i<N_LIST; i++){
            double c_currentdouble=sin(i*dt*ang_frequency);
            double c_currenttime=dt*i;
            PyObject* py_currentdoubley=Py_BuildValue("d",c_currentdouble);
            PyObject* py_currenttime=Py_BuildValue("d",c_currenttime);
            PyList_SetItem(py_listy,i,py_currentdoubley);
            PyList_SetItem(py_listx,i,py_currenttime);
        }
        //call the python and pass the data generated in C
        //------------------------------------------------------------------------------------------------------
        if(py_function&&PyCallable_Check(py_function)){
            pid_t pid=fork();
            if(pid==0){
                PyObject* res=PyObject_CallFunctionObjArgs(py_function,py_listx,py_listy,NULL);
                return EXIT_SUCCESS;
            }
        }
        //------------------------------------------------------------------------------------------------------
        else{
            printf("Could not create function object.");
            printf("\n%d",py_function);
            return EXIT_FAILURE;
        }
    }
    else{
        printf("Cannot find module.");
        return EXIT_FAILURE;
    }
    printf("Exiting program\n");
    return EXIT_SUCCESS;
}

包含 plotFunction(argx,argy) 的 Python 脚本:

import matplotlib.pyplot as plt
import numpy as np

def plotFunction(argx,argy):
    if type(argx)==list or type(argx)==np.ndarray and type(argy)==list or type(argy)==np.ndarray:
        plt.plot(argx,argy)
        plt.grid()
        plt.show()
    else:
        print("Not all arguments passed are lists. Call failed.")

最佳答案

如果你想坚持使用 python,你可以在一个新线程而不是一个全新的进程中调用函数。如果你有 C++11 std::thread,这很容易但你也可以使用 QtThread .

更简单的方法是使用 QtCharts虽然并直接在 C++ 中绘制。

第三种方式是 save从 python 到图像的绘图并在 Qt 中显示该图像。

关于c++ - 使用 Python 的 Matplotlib 绘制在 C++ 程序中生成的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53822542/

相关文章:

python-3.x - 无法在 .rst toctree Sphinx 中显示多个 .md 文件

python - psycopg2.编程错误: column of relation does not exist

python - 在 Python 3 CGI 中使用 matplotlib

c++ - 未找到 SSPI 协商

c++ - 如何检测对临时对象成员的引用

python - 如何写入 CSV 而不覆盖过去的文本

Matplotlib Colorbar 缺少 1 个必需的位置参数 : 'mappable'

python-3.x - 找不到 matplotlib 数据文件

c++ - 取消引用 null 并不总是 UB?

c++ - 循环执行