Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save plots from multiple python scripts using an interactive C# process command?

I've been trying to save plots(multiple) from different scripts using an interactive C# process command.

Objective: My aim is to save plots by executing multiple scripts in a single interactive python shell and that too from C#.

Here's the code which I've tried from my end.

Code snippet:

class Program
{
    static string data = string.Empty;
    static void Main(string[] args)
    {
        Process pythonProcess = new Process();
        ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe", "/c" + "python.exe -i");
        startInfo.WorkingDirectory = "C:\\python";
        startInfo.CreateNoWindow = true;
        startInfo.UseShellExecute = false;
        startInfo.RedirectStandardInput = true;
        startInfo.RedirectStandardOutput = true;
        startInfo.RedirectStandardError = true;
        pythonProcess.StartInfo = startInfo;
        pythonProcess.ErrorDataReceived += Process_ErrorDataReceived;
        pythonProcess.OutputDataReceived += Process_OutputDataReceived;
        pythonProcess.Start();
        pythonProcess.BeginErrorReadLine();
        pythonProcess.BeginOutputReadLine();
        Thread.Sleep(5000);

        while (data != string.Empty)
        {
            if (data == "Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.")
            {
                pythonProcess.StandardInput.WriteLine("execfile('script1.py')");
                pythonProcess.StandardInput.WriteLine("execfile('script2.py')");
                break;
            }
        }
        pythonProcess.WaitForExit();
    }

    private static void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        data = e.Data;
    }

    private static void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        data = e.Data;
    }
}

Scripts:

script1.py

import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 5, 0.1);
y = np.sin(x)
plt.plot(x, y)
plt.savefig('script1.png')

script2.py

import matplotlib.pyplot as plt
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
plt.savefig('script2.png')

From the above C# code, you could see that I've tried to execute both the scripts. But, during the execution, the plot from the first script (script1.py) alone gets saved, whereas the second one (script2.py) doesn't.

All I need to know is, how come the second script plot doesn't gets saved and what's the reason behind this ?

Thanks in advance :)

like image 211
Ramkumar Avatar asked Sep 09 '16 06:09

Ramkumar


1 Answers

Since you are opening a python shell and then sending it the commands:

execfile('script1.py')
execfile('script2.py')

Immediately one after the other I suspect that the second command is being sent during time taken to load numpy and matplotlib - you need to check the output from the first execfile to make sure that it has finished before issuing the second, or you need to use a different thread for each - at the moment you have a single thread attempting to perform two separate actions almost at once.

Note that once you have finished with your python shell it is a very good idea to exit it by sending exit() to the process stdin and calling process.WaitForExit().

Also note that using a shell to call python code and execute external threads is classed as a security vulnerability in addition to being slow, reliant on the user having python installed, etc., you might be better off looking at using IronPython - but the only actively maintained plotting library that I was able to find is the non-free ILNumerics Visualization Engine.

like image 133
Steve Barnes Avatar answered Oct 29 '22 04:10

Steve Barnes