繁体   English   中英

如何以交互模式将带有matplotlib的Python代码嵌入C中?

[英]How to embed Python code with matplotlib in interactive mode into C?

我想通过从C应用程序中嵌入对Matplotlib的调用来重用以交互模式使用的Python脚本-为了使交互模式在嵌入式Python脚本中正常工作,我需要做什么?

我使用PyRun_SimpleString()建立了一个非常简单的示例; 它在关闭交互模式时有效,但是在交互模式处于打开状态时,绘图窗口仅在应用程序结束前短暂显示

#include <Python.h>

int
main(int argc, char *argv[])
{
    wchar_t *program = Py_DecodeLocale(argv[0], NULL);
    if (program == NULL) {
        fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
        exit(1);
    }
    Py_SetProgramName(program);  /* optional but recommended */
    Py_Initialize();
    PyRun_SimpleString("from time import time,ctime,sleep\n"
                       "import matplotlib.pyplot as plt\n"
                       "import matplotlib\n"
                       "print(matplotlib.get_backend())\n"
                       "plt.ion()\n"
                       "plt.plot([1,2,3,4,3,5,7])\n"
                       "sleep(5)\n");
    Py_Finalize();
    PyMem_RawFree(program);
    return 0;
}

matplotlib使用的后端是Qt4Agg。 当我在Python解释器中执行以上各行时,它的行为符合我的预期。 如果我将plt.ion()更改为plt.ioff()并在plt.plot()调用之后放入plt.show(),我也会看到该图。

我假设当您说“ [w]当我在Python解释器中执行以上代码时,它的行为符合我的期望”,您指的是在Python命令行/ REPL中运行它。 测试嵌入式Python一对一行为的正确方法是将您放置在python脚本中,然后尝试使用python script.py运行它。

您会注意到,在脚本内,您的代码也遇到类似的问题。 我认为诀窍是使用plt.pause(5)而不是sleep(5) ,这将允许绘图GUI触发事件循环并实际正确绘制窗口( https://stackoverflow.com/a/35119003/ 11365663 )。

对于REPL,matplotlib具有一些额外的魔力,因此您可以隐藏事件循环的详细信息。

这为我工作:

#include <Python.h>

int
main(int argc, char *argv[])
{
    wchar_t *program = Py_DecodeLocale(argv[0], NULL);
    if (program == NULL) {
        fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
        exit(1);
    }
    Py_SetProgramName(program);  /* optional but recommended */
    Py_Initialize();
    PyRun_SimpleString("from time import time,ctime,sleep\n"
                       "import matplotlib.pyplot as plt\n"
                       "import matplotlib\n"
                       "print(matplotlib.get_backend())\n"
                       "plt.ion()\n"
                       "plt.plot([1,2,3,4,3,5,7])\n"
                       "plt.pause(5)\n");
    Py_Finalize();
    PyMem_RawFree(program);
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM