Matplotlib ion() and subprocesses

2019-01-26 10:41发布

问题:

I am trying to have a plot pop up so the user can confirm that a fitting worked, but not hang up the entire process doing so. However, while the window appears, there is never anything in it, and it is "Not Responding". I suspect that there is a bad interaction with the subprocess functionality, as this code is front-ending and data processing for a simulation being run in C++.

import subprocess
import numpy as np
from matplotlib import pyplot as mpl
...
mpl.ion()
fig = mpl.figure()
ax = fig.add_subplot(1,1,1)
ax.grid(True)
ax.plot(x, y, 'g')
ax.scatter(X, Y, c='b')
ax.scatter(min_tilt, min_energy, c='r')
mpl.draw()
...
subprocess.call(prog)

The following subprocess does open. If I remove the ion() call and use mpl.show(), then the plot works fine, but the entire process holds up until the window is closed. I need the process to continue while the user looks at the graph. Is there a way to do this?

回答1:

Instead of the mpl.draw(), try:

mpl.pause(0.001)

when using the matplotlib interactive mode ion(). Note that this only works from matplotlib 1.1.1 RC or higher.



回答2:

This is probably overkill, but since no one had any better solutions I went to the threading module and it worked. If anyone has a simpler way to do this, please let me know.

import subprocess
import threading
from matplotlib import pyplot as mpl
...
class Graph(threading.Thread):
   def __init__(self,X,Y,min_tilt, min_energy):
       self.X = X
       self.Y = Y
       self.min_tilt = min_tilt
       self.min_energy = min_energy
       threading.Thread.__init__(self)

   def run(self):
       X = self.X
       Y = self.Y
       dx = (X.max()-X.min())/30.0
       x = np.arange(X.min(),X.max()+dx,dx)
       y = quad(x,fit)
       fig = mpl.figure()
       ax = fig.add_subplot(1,1,1)
       ax.grid(True)
       ax.plot(x, y, 'g')
       ax.scatter(X, Y, c='b')
       ax.scatter(self.min_tilt, self.min_energy, c='r')
       mpl.show()
thread = Graph(X,Y,min_tilt,min_energy)
thread.start()