I originally posted this to the user's list but got no response there.  As I
think there's a bug in matplotlib here, I'm re-trying on the development
list.  Here's what I sent to -users back on Mar 13:

I am using matplotlib's object-oriented API to dynamically generate some
graphs served by a web site.  The web site is built with Django and I have
generally followed the cookbook example I found here:
http://www.scipy.org/Cookbook/Matplotlib/Django for serving matplotlib
figures under Django.  Specifically my code looks like this:

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure

def generate_png(request, f, year, cid, pid, ic):

    # ...snipped code that generates the data to graph...

    fig = Figure()
    ax = fig.add_subplot(111)
    ax.set_title(fig_title)
    ax.set_xlabel("Score")
    ax.set_ylabel("Frequency")
    n, bins2, patches = ax.hist(vals, bins, facecolor='blue',
edgecolor='blue')
    if x is not None:
        patches[x].set_facecolor('red')
        patches[x].set_edgecolor('red')
        fig.legend((patches[x],), ('%s (%d)' % (cname, cval),), 'lower
left')
    canvas = FigureCanvas(fig)
    canvas.print_png(f)

    # ... snip remainder ...

This works fine, except when I run it under a multi-threaded web server
(Apache with mod_wsgi in daemon mode with multi-threaded processes) it
sometimes (not always) fails with this traceback:

 File "/home/kmt/django/Django-1.1-alpha-1/django/core/handlers/base.py",
line 86, in get_response
   response = callback(request, *callback_args, **callback_kwargs)
 File "/home/kmt/software/web/xword/acpt/views.py", line 321, in get_png
   response = generate_png(request, f, year, cid, pid, ic)
 File "/home/kmt/software/web/xword/acpt/views.py", line 308, in
generate_png
   canvas.print_png(f)
 File "/usr/lib/python2.5/site-packages/matplotlib/backends/backend_agg.py",
line 305, in print_png
   FigureCanvasAgg.draw(self)
 File "/usr/lib/python2.5/site-packages/matplotlib/backends/backend_agg.py",
line 261, in draw
   self.figure.draw(self.renderer)
 File "/usr/lib/python2.5/site-packages/matplotlib/figure.py", line 765, in
draw
   legend.draw(renderer)
 File "/usr/lib/python2.5/site-packages/matplotlib/legend.py", line 215, in
draw
   t.draw(renderer)
 File "/usr/lib/python2.5/site-packages/matplotlib/text.py", line 329, in
draw
   ismath=self.is_math_text(line))
 File "/usr/lib/python2.5/site-packages/matplotlib/backends/backend_agg.py",
line 113, in draw_text
   self._renderer.draw_text_image(font.get_image(), int(x), int(y) + 1,
angle, gc)
RuntimeError: You must call .set_text() before .get_image()

I'm not at all familiar with the internals (truly I'm barely familiar with
the public APIs) of matplotlib but it appears from this exception that
internally there's a 'font' object being shared between threads here, such
that one thread can come in and change the font state resulting in a
subsequent error in a different thread that was also in the middle of using
that font object?  If I protect that block of code above with a thread lock
so that only one thread is allowed in at a time, the problem goes away.

For reference I'm using the latest matplotlib available in the Ubuntu
Intrepid (8.10) repositories, which looks to be 0.98.3.  In a brief scan I
didn't see anything relevant listed in the "what's new" page for 0.98.4 (and
can't find a "what's new in 0.98.5" on the matplotlib web site though that
is what is listed as most recent?).  Nor can I find anything that looks
similar logged as a bug in the tracker.

Is there something (besides bracketing all access to the matplotlib code
with a thread mutex) that I should be doing to make my use of matplotlib
thread safe or does it seem like there's a multi-threading bug in matplotlib
here?

Apologies if this is the wrong list and there is in fact something I ought
to be doing in my code (other than using a mutex) to prevent this -- I
haven't been able to find anything.  My impression from various doc I've
read is the object-oriented API is supposed to be thread-safe.  Is that
true?  If so should I file a ticket for this?

Thanks for any feedback,
Karen
------------------------------------------------------------------------------
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to