1

Does anyone know how to let matplotlib (V3.3.0) to show a figure and then continue executing the rest of the Python script when executed from Python.NET PythoneEngine.Exec(script) in a C# app?

plt.show(block=False)

This works as expected.

When I run the same script directly from Python interpreter V3.8.4 (64 bit) it works. So, I think that all the libraries are installed correctly. I'm using the following code:

class Program
{
    static void Main(string[] args)
    {
        PythonEngine.Initialize();

        using (Py.GIL())
        {
            var script = "import matplotlib.pyplot as plt\n"
                         + "import numpy as np\n"
                         + "x = np.arange(0.0, 2.0, 0.01)\n"
                         + "y = np.sin(2 * np.pi * x)\n"
                         + "fig, ax = plt.subplots()\n"
                         + "ax.plot(x, y)\n"
                         + "plt.show(block=False)\n";
            PythonEngine.Exec(script);
        }
        
        Console.ReadLine();
        PythonEngine.Shutdown();
    }
}

This shows a blank window when PythoneEngine.Exec() finishes. The figure window itself is unresponsive. If I remove block=False from the plt.show(block=False), then it shows the sine curve correctly. But I have to close the figure window to let it continue.

I'm using .NET Framework 4.8 on Windows 10 (64 bit).

finefoot
  • 9,914
  • 7
  • 59
  • 102
tetsushmz
  • 11
  • 2

2 Answers2

0

You need to call PythonEngine.BeginAllowThreads() to initialize Python threading support: https://github.com/pythonnet/pythonnet/wiki/Threading

LOST
  • 2,956
  • 3
  • 25
  • 40
  • I added it between Inititalize() and GIL(). But it made no difference. I dug through matplotlib source code and the last statement in show(block=False) is "yield". I'm wondering if it's not working with Python.NET? – tetsushmz Jul 29 '20 at 12:06
  • Hm. Maybe the issue is not with Python.NET: https://stackoverflow.com/questions/28269157/plotting-in-a-non-blocking-way-with-matplotlib – LOST Jul 29 '20 at 17:08
  • 1
    I saw the SO. I tried ion() and pause(). Nothing works. Because my code works when executed from Python interpreter, I still think that the issue can be in Python.NET. – tetsushmz Jul 29 '20 at 18:18
0

I resolved the issue of the blank window. But the solution requires the message pump, which is an infinite loop, after PythonEngine.Exec(script). In that sense, it does not behave like the real Python interpreter that shows the ">>>" prompt right after the plt.show(block=False) is executed.

Still, I want to leave the code here for anyone who happens to come across this SO question.

static void Main(string[] args)
{
    PythonEngine.Initialize();
    dynamic root;
    using (Py.GIL())
    {
        var script = "import matplotlib.pyplot as plt\n"
                     + "import numpy as np\n"
                     + "x = np.arange(0.0, 2.0, 0.01)\n"
                     + "y = np.sin(2 * np.pi * x)\n"
                     + "fig, ax = plt.subplots()\n"
                     + "ax.plot(x, y)\n"
                     + "plt.show(block=False)\n";
        PythonEngine.Exec(script);
        dynamic pyplt = Py.Import("matplotlib.pyplot");
        root = pyplt.figure().canvas.manager.window;
    }

    while (true)
    {
        using (Py.GIL())
        {
            root.update_idletasks();
            root.update();
        }

        Thread.Sleep(1);
    }
}

My actual application is a WPF app, rather than the console, and needs to show multiple matplotlib windows. I will still need to manage the thread such that only a single thread is used to run the script. Otherwise, a PythonException with "RuntimeError : main thread is not in main loop" message is thrown deep inside matplotlib call chain when PythonEngine.Exec(script) is executed for the second time (to show the second matplotlib window).

tetsushmz
  • 11
  • 2
  • Hi, I am using the same process which you are doing but we are using Html and .net API. So we don't have WPF. How can we plot the matplotlib chart in HTML? I am searching for this scenario for so many days. Could you please help me to solve this issue – mani Jun 08 '21 at 05:02