Matplotlib ion() and subprocesses
Asked Answered
M

2

7

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?

Moschatel answered 14/7, 2012 at 1:7 Comment(0)
M
1

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()
Moschatel answered 17/7, 2012 at 20:54 Comment(1)
Hmm it looks like this causes issues if the preceding window does not get closed before the next one is opened. Anyone know how to fix this so it can open as many windows as needed?Moschatel
E
8

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.

Employ answered 15/7, 2012 at 12:28 Comment(3)
This does draw the window and continue the processing, but the window immediately goes to "not responding" and closing it stops the whole process.Moschatel
@Elliot: Do you get the same effect when you do a plt.show(block=False) with interactive mode off?Menarche
While adding mpl.pause(0.0001) instead of mpl.draw() managed to display the plot, whenever I try to click on it, the window goes to the "Not Responding" state. Anyone has an idea explaining this?Wolenik
M
1

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()
Moschatel answered 17/7, 2012 at 20:54 Comment(1)
Hmm it looks like this causes issues if the preceding window does not get closed before the next one is opened. Anyone know how to fix this so it can open as many windows as needed?Moschatel

© 2022 - 2024 — McMap. All rights reserved.