3

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.

Community
  • 1
  • 1
cpaitor
  • 423
  • 1
  • 3
  • 16

1 Answers1

0

spawn it similar to there: How to start 2x Matplotlib interactiv windows, viewer of another main window? . make sure you spawn it with mp.set_start_method('spawn') and include matplotlib in the spanned function. Something similar to the code below (NOT tested)

import matplotlib, multiprocessing

matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

def plot(): 
   import matplotlib
   fig = matplotlib.pyplot.figure()
   fig.show()    

plot()
multiprocessing.set_start_method('spawn') 
p = multiprocessing.Process(target=plot, args=())
p.start() 
raw_input()
floppy_molly
  • 175
  • 1
  • 10