简体   繁体   中英

matplotlib freezes when called after tkinter mainloop

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

Since I could not find any answer to this issue, I came up with a workaround: I used an other backend with matplotlib, not relying on Tk. I chose Qt4Agg since I did not manage to make the other ones work.

To do so, simply add

import matplotlib
matplotlib.use("qt4agg")

before importing pyplot. You can also use

import matplotlib.pyplot as plt
plt.switch_backend("backend")

This can be done after importing pyplot, but note that this is an experimental feature !

I had to change a few things in the code after switching the backend. For example the plot window did not pop up or update unless I called plt.pause(.01), which was not necessary with TkAgg.

I consider this self-reply to be only a partial solution since it does not solve nor explain the issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM