python - Matplotlib can't render multiple contour plots on Django -


whenever (at least) 2 people try generate contour plot in application, @ least 1 of them receive random error depending on how far first person managed draw.. ("unknown element o", "contourset must in current axes" 2 of possibilities)

the following cut down test can produce error, if try load page in 2 or more tabs @ once, first render correctly whilst second produce error. (easiest way found click refresh page button in chrome middle mouse button couple times)

views.py

def home(request):     return render(request, 'home.html', {'chart': _test_chart()})   def _test_chart():     import base64     import cstringio     import matplotlib     matplotlib.use('agg')     matplotlib.mlab import bivariate_normal     import matplotlib.pyplot plt     import numpy np     numpy.core.multiarray import arange      delta = 0.5      x = arange(-3.0, 4.001, delta)     y = arange(-4.0, 3.001, delta)     x, y = np.meshgrid(x, y)     z1 = bivariate_normal(x, y, 1.0, 1.0, 0.0, 0.0)     z2 = bivariate_normal(x, y, 1.5, 0.5, 1, 1)     z = (z1 - z2) * 10      fig = plt.figure(figsize=(10, 5))     plt.contour(x, y, z, 10, colors='k')      jpg_image_buffer = cstringio.stringio()     fig.savefig(jpg_image_buffer)      array = base64.b64encode(jpg_image_buffer.getvalue())     jpg_image_buffer.close()     return array 

home.html (just 1 line enough)

<img src="data:image/png;base64,{{ chart }}" /> 

i've tried using mpld3 instead handle generation of image , still produces different errors know not saving of figure more generation. i've tried using threadpool , threading no avail, can tell seems creating contour plot in matplotlib cannot support multiple instances never work website...

my clear solution can think of right replace matplotlib else don't want do.

is there way generate contour plots matplotlib work me?

first, let me start saying more easy reproduce calling _test_chart in couple threads

from threading import thread in xrange(2):     thread(target=_test_chart).start() 

doing above, 1 work desired whilst second 1 crash.


the simple reason pyplot module not designed multithreading , therefore 2 charts getting data mixed attempt draw.

this can better explained mdboom

...pyplot used convenient plotting @ commandline , keeps around global state. example, when plt.figure() adds figure global list , sets "current figure" pointer created figure. subsequent plotting commands automatically write figure. obviously, that's not threadsafe...

there 2 ways fix issue,

  1. force these charts drawn in different processes.
for in xrange(2):     pool = pool(processes=1)     pool.apply(_test_chart)    

whilst work find there noticable drop in performance since take long create process generate chart (which didn't think acceptable!)

  1. the real solution use oo interface modules of matplotlib allow work correct objects - works down working subplots rather plots. given example in question, following
def _test_chart2():      delta = 0.5      x = arange(-3.0, 4.001, delta)     y = arange(-4.0, 3.001, delta)     x, y = np.meshgrid(x, y)     z1 = bivariate_normal(x, y, 1.0, 1.0, 0.0, 0.0)     z2 = bivariate_normal(x, y, 1.5, 0.5, 1, 1)     z = (z1 - z2) * 10      fig = figure(figsize=(10, 5))      ax1 = fig.add_subplot(111)     extents = [x.min(), x.max(), y.min(), y.max()]     im = ax1.imshow(z,                     interpolation='spline36',                     extent=extents,                     origin='lower',                     aspect='auto',                     cmap=cm.jet)     ax1.contour(x, y, z, 10, colors='k')      jpg_image_buffer = cstringio.stringio()     fig.savefig(jpg_image_buffer)      array = base64.b64encode(jpg_image_buffer.getvalue())     jpg_image_buffer.close()      return array 

Comments

Popular posts from this blog

qt - Using float or double for own QML classes -

Create Outlook appointment via C# .Net -

ios - Swift Array Resetting Itself -