Is there a way to use matplotlib
from both the main function and from spawned processes?
In my current application I wish to plot intermediate results of a simulation and do so by spawning a subprocess using the multiprocessing
module to allow the simulation to carry on in the background and the user to option to close or keep plot(s) open. At a certain point the continued simulation can be modified by the user, thus the main function plots the results so far and awaits the user response. However, in doing so the program chrashes with the error message:
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
python: xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
Aborted
The program runs fine if I remove the plotting of intermediate steps in sub-processes or skips the plotting in the main function.
For now I've circumvented the problem by spawning yet another sub-process to do the plotting and retrieve the user input (using multiprocessing.Queue()
and the join()
method). However it seems a bit superflous having to do this, thus I really would appreciate if there's some better way to do this.
Looking into the stackoverflow archives I found a post reporting upon the same error were it is commented that "matplotlib does not work well with multiprocessing." but no solution/workaround is suggested.
The following code reproduces the problem:
#! /usr/bin/env python
import matplotlib, multiprocessing
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
def plot():
fig = matplotlib.pyplot.figure()
fig.show()
plot()
p = multiprocessing.Process(target=plot, args=())
p.start()
raw_input()
As a side note, I find that simply using import matplotlib
the code chokes on fig = matplotlib.pyplot.figure()
while including import matplotlib.pyplot as plt
the code runs fine which is a bit strange as I were under impression that in this case plt
but not matplotlib.pyplot
should be accessible.