Apache hangs with Django / Matplotlib app
Question: new StackOverflow user here. I need help with an Apache freezing problem. I
have a WAMPServer setup on Win 7 64-bit and am working with python / django /
mysql / mod_wsgi / matplotlib, experimenting with dynamically rendered images.
I am using Apache to serve static files.

I am trying to plot data from a MySQL database. My views.py file is below.
When I invoke the function "view_Stats" by visiting the appropriate web page,
this calls the "CreateFig" function to create and save .png files to a
directory that are subsequently served by Apache. It works fine initially, but
it seems as if a maximum of 8 calls can be made to the "CreateFig" function
before Apache just hangs. I have to restart Apache at that point, but it takes
a while (minutes) for it to restart.

Looking at the Apache error logs (see below) shows an error related to Apache
child processes that requires Apache to force it to terminate. I suspect some
sort of memory leak / error, but I'm pretty new at this and can't troubleshoot
well; I've Googled this and looked around on StackOverflow, no joy.

Any help would be appreciated!

    
    
    [Tue Mar 11 17:01:07.550093 2014] [core:notice] [pid 2820:tid 404] AH00094: Command line: 'c:\\wamp\\bin\\apache\\apache2.4.4\\bin\\httpd.exe -d C:/wamp/bin/apache/Apache2.4.4'
    [Tue Mar 11 17:01:07.551093 2014] [mpm_winnt:notice] [pid 2820:tid 404] AH00418: Parent: Created child process 3528
    [Tue Mar 11 17:01:07.856093 2014] [mpm_winnt:notice] [pid 3528:tid 324] AH00354: Child: Starting 150 worker threads.
    [Tue Mar 11 17:04:53.233893 2014] [mpm_winnt:notice] [pid 2820:tid 404] AH00422: Parent: Received shutdown signal -- Shutting down the server.
    [Tue Mar 11 17:05:23.248293 2014] [mpm_winnt:notice] [pid 2820:tid 404] AH00431: Parent: Forcing termination of child process 3528
    

The Code from views.py is below:

    
    
    from django.contrib import auth
    from django.contrib.auth.models import User, Group
    from django.core.context_processors import csrf
    from django.shortcuts import render_to_response
    from django.http import Http404, HttpResponseRedirect
    
    from rwjcnlab import settings
    from clientele.models import UserProfile
    from reports.models import EEG, LTM, EMU, AEEG
    
    import os, datetime
    import numpy
    from pylab import *
    import matplotlib.pyplot as plt; plt.rcdefaults()
    import matplotlib.pyplot as plt
    import gc
    
    
    # CREATE VIEWS HERE
    def view_Stats(request):
        UID = UserProfile.objects.get(user_id = request.user.id)
        StatsEEG, StatsLTM, StatsAEEG, StatsEMU, start_date = ReportNumbers(UID.id)
    
        # Create figures
        CreateFig(StatsEEG, 300, 50, 'EEG', 'b')
        CreateFig(StatsLTM, 100, 10, 'LTM', 'r')
        CreateFig(StatsAEEG, 15, 3, 'AEEG', 'y')
        CreateFig(StatsEMU, 25, 5, 'EMU', 'c')
    
        return render_to_response('view_Stats.html', {
            'StatsEEG': StatsEEG,
            'StatsLTM': StatsLTM,
            'StatsAEEG': StatsAEEG,
            'StatsEMU': StatsEMU,
            'start_date': start_date,
            'user': request.user,
        })
    
    def CreateFig(Stats, ymax, yinc, figname, c):
        nAll    = tuple(x[1] for x in Stats)
        nUser   = tuple(x[2] for x in Stats)
        xlabels = tuple(x[0].strftime("%b%y") for x in Stats)
    
        ind     = numpy.arange(len(xlabels)-1.4,-0.4,-1)    # the x locations for the groups
        width   = 0.8                                       # the width of the bars: can also be len(x) sequence
    
        plt.ioff()
        fig = plt.figure(figsize=(10, 5), dpi=72, facecolor='w', edgecolor='k')
        p1 = plt.bar(ind, nAll[1:], width, color=c)
        p2 = plt.bar(ind, nUser[1:], width, color='g')
        plt.title(figname+' Volumes at RWJUH')
        plt.xticks(ind+width/2., xlabels[1:])
        plt.yticks(numpy.arange(0,ymax,yinc))
        plt.legend( (p1[0], p2[0]), ('Total', 'User') )
        plt.savefig(os.path.join(settings.BASE_DIR, 'static/'+figname+'.png'))
    
        fig.clf()
        plt.close(fig)
        gc.collect()
    
        return
    


Answer: This is likely because you're trying to connect to a (presumably non-existent)
X-server when you use matplotlib. If you do have X running on your webserver,
you probably still want to avoid using an interactive backend for matplotlib

(_Edit_ : Just saw that you're on windows. Obviously, it's not that
mattplotlib is trying to connect to an X-server when run on Windows, but I'd
be willing to bet that your problem is still related to using an interactive
backend and matplotlib trying to connect to the graphical display.)

If you want to use matplotlib without interactive plots (i.e. without needing
an X-server), then you need to explicitly use a non-interactive backend. (e.g.
`Agg`, `pdf`, etc)

First off, remove `from pylab import *`. That's a really bad idea for a huge
number of reasons (hint, `min` and `max` aren't what you think they are, among
other things). Also, you don't seem to be using it. You're already accessing
matplotlib functionality through the pyplot interface and `numpy` though the
numpy namespace.

Next, _before_ you do `import matplotlib.pyplot as plt` (or before you do
`from pylab import *` if you decide not to remove it), do:

    
    
    import matplotlib
    matplotlib.use('Agg')
    import matplotlib.pyplot # etc...
    

Now matplotlib won't try to connect to the X display everytime you make a new
figure.

