Making Dynamic Charts and Graphs for Your WebPage

Today I describe how I will make data-driven charts and graphs for an intranet site I’m developing. After an hour of researching the Python graphing libraries out there, I decided to go with Matplotlib for the chart generation. It seemed like the most server friendly option because it seems to run fast and it required me to install the least amount of other programs. (Plus this guy really likes it.)

Here is the chart image I’m able to make so far (code below):
Matplotlib Example
It’s not pretty yet, but this post is focusing on the cgi mechanics. I’ll update you when I learn the intricacies of plotting data in Matplotlib.

One thing to note about using Matplotlib for this purpose is that it insists on saving its output to a file and on top of that, it requires a filename (not a file object). So that means that printing the image data directly to STDOUT like I wanted was out of the question and so was using cStringIO to make a pretend, in-memory file. Thus I was forced to use a temp file approach*.

Here is the code. It makes a PNG file of a plot with two plot lines. This script should be saved in its own file, placed in a cgi-bin location and referenced via URL. You’ll need to install Matplotlib and Numeric to run this code. You’ll also want to modify it to do something useful ;-)

#!/usr/bin/env python
import os
import tempfile
import matplotlib
matplotlib.use('Agg')  # force the antigrain backend
from matplotlib import rc
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure
from matplotlib.cbook import iterable
import matplotlib.numerix as nx

def make_fig():
    """ make a chart """
    fig = Figure()
    # add an axes at left, bottom, width, height; by making the bottom
    # at 0.3, we save some extra room for tick labels
    ax = fig.add_axes([0.2, 0.3, 0.7, 0.6]) #ie set sides of chart box
    #now we make the plots
    line,  = ax.plot([0,2,3,4],[100,200,230,250], 'ro--', markersize=12, markerfacecolor='g',label='Meters', linewidth=2)
    line,  = ax.plot([0,2,4],[1.5,25,3.5], 'bv--', markersize=12, markerfacecolor='g',label='Checks', linewidth=2)
    ax.legend() #stick in a legend
    # add some text decoration
    ax.set_title('Sales to Blue Credit')
    ax.set_xticks( (0,1,2,3,4) ) #set these the same as x input into plot
    labels = ax.set_xticklabels(('2006-01-01', '2006-01-15', '2006-02-01', '2006-03-01'))
    canvas = FigureCanvasAgg(fig)

    #now let's handle the temp file stuff and print the output
    tempfilenum,tempfilename=tempfile.mkstemp(suffix='.png') #function print_figure below requires a suffix
    canvas.print_figure(tempfilename, dpi=150)
    print "Content-type: image/png\\n"
    os.close(tempfilenum) #close what tempfile.mkstemp opened
    os.remove(tempfilename) #clean up by removing this temp file

if __name__=='__main__':

So this script is a a combination of the general web server example from the Matplotlib examples and my temporary file stuff at the end in order to get my script (call it “”) to produce an image when called upon i.e. when browsing to it or referencing it from an <img src="" /> type of deal.

The next step for me is to start customizing this code further and actually make some useful dynamic charts from live company data.

1. Serving Dynamic Images with Python CGI was of great help.
2. so was Displaying Random Images with Simple Python CGI.
3. Python tempfile module documentation which I wish had examples :-(

*But this is a bonus for you, gentle reader as I’ve found there to be a dearth of examples of how to actually use temporary files in Python. So consider this a useful addition to the stock of temporary file usage examples in Python on the internet. (assuming I did it right ;-) )

[tags]Matplotlib, Matplotlib Python, Matplotlib Example, Matplotlib Examples, Python, Python Examples, Dynamic Charts, Data Visualization, Dynamic graphs, plots, Python plots, Data Mining, Data-Mining, tempfile, python tempfile, temporary files, tempfile example[/tags]

2 Responses to “Making Dynamic Charts and Graphs for Your WebPage”

  1. Jenny says:

    The line:
    “Content-type: image/pngn”
    should be:
    “Content-type: image/png\n”

  2. Thanks, Jenny. I updated this post with the change.