I have been facing an issue that implies Matplotlib, Tkinter and multiprocessing.Process:
I wrote a program that creates a Tkinter window to ask the user for input. Once the tkinter window is closed, it spawns several processes, some of which plot data with matplotlib. I run the program with Python 2.7.6 and Linux (Ubuntu 14.04).
Both parts work fine on their own, only when put together they crash, display the following error and sometimes even freeze the X server.
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0.0"
after 167 requests (167 known processed) with 17 events remaining.
XIO: fatal IO error 0 (Success) on X server ":0.0"
after 171 requests (171 known processed) with 19 events remaining.
This piece of code systematically reproduces the issue for me:
import Tkinter as tk
from time import sleep
from multiprocessing import Process
import matplotlib.pyplot as plt
class Plotter(Process):
"""
A minimalist version of the plotting process, to illustrate
"""
def run(self):
f = plt.figure()
plt.show(block=False)
while True:
sleep(.2)
f.canvas.draw()
print("-Loop")
if __name__ == "__main__":
# If these two lines are commented, the two mpl windows show up
# and both processes loop fine
root = tk.Tk()
root.mainloop() # Wait for the user to quit the main window
# End of the first part: the Tkinter window is now closed
p1 = Plotter()
p2 = Plotter()
p1.start()
p2.start() # If this line is commented, the program runs fine
This program will pop a tkinter window. When closed by the user, the program crashes, sometimes causing all the windows to lock up until Python is killed through the tty. The interesting part is that if only one of the processes is started, it runs fine. More interestingly, if the Tkinter window is omitted, everything runs fine, even with two or more processes. As far as i tested, the crash only happens with tkinter AND two or more processes creating matplotlib figures.
I tested this program on two different machines, with matplotlib 1.3.1 and 2.0.2, the same problem occurs on both. I am probably missing a subtle interaction between matplotlib and tkinter, but i would expect this code to run the two processes, even if a tkinter app was closed before.
Does anyone know why this happens ? How can i spawn processes using matplotlib after a tkinter window's mainloop method ?
Thank you