【问题标题】:How to embed Python code with matplotlib in interactive mode into C?如何以交互模式将 Python 代码与 matplotlib 嵌入到 C 中?
【发布时间】:2019-09-07 04:40:36
【问题描述】:

我想通过嵌入来自 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() ,我也会看到情节。

【问题讨论】:

    标签: python c matplotlib


    【解决方案1】:

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

    您会注意到在脚本中您的代码会出现类似的问题。我认为诀窍是使用plt.pause(5) 而不是sleep(5),这允许绘图GUI 的事件循环触发并实际正确绘制窗口(@98​​7654321@)。

    对于 REPL,matplotlib 有一些 extra magic,因此事件循环的细节对你来说是隐藏的。

    这对我有用:

    #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;
    }
    

    【讨论】:

    • 非常感谢您的解释——您所做的关于偶数循环的 cmets 非常有意义,并且引入了 pause() 调用就成功了——感谢您指出在也可以使用 matplotlib。感谢您的帮助...
    猜你喜欢
    • 1970-01-01
    • 2014-05-09
    • 2012-06-23
    • 2017-08-24
    • 2015-08-20
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多