has anyone got matplotlib to work in a cgi script on Apache?

Hi, The code below when run from a file in the cgi-bin

    > directory should generate a plot but it does not work:

It would help to have more information. What do you mean "does not
work"? Are there any errors displayed to the terminal or apache
logs. I know people have used mpl with apache, but it can be a little
tricky to get all the data paths set up properly.

matplotlib uses a couple of environment variables to find it's data
and store cache information. For example, if your fonts and
.matplotlibrc are in a nonstandard place, you need to set the env var
MATPLOTLIBDATA to point to them. Also, mpl tries to create a cache
file .ttffont.cache in your HOME dir by default, and in an apache
config HOME may not exist or may not be writable. If there is no
HOME, matplotlib will fall back on the MATPLOTLIBDATA dir, so make
sure env var is set, that it points to the directory that contains
Vera.ttf and the other mpl fonts, and that it is writable by the user
under which apache runs.

If you get this to work, please write a HOWTO and submit it to the list.

    > #!d:/apps/Python23/python

    > import sys import matplotlib matplotlib.use('Agg') from
    > pylab import *

    > plot([1,2,3,4])

    > #print "Content-type: text/html\n\n" #print "<html>Hello
    > world!</html>"

    > print "Content-type: image/png\n\n"
    > print savefig(sys.stdout)

This looks wrong. Doing

print savefig(sys.stdout)

will also print the return value of savefig, which is None I believe.
I think you just want

savefig(sys.stdout)

But I can't vouch for the overall approach (setting the content type
and then dumping in a binary stream of the png). It may be correct,
but I haven't used it. Somehow I would expect the stream to be mime
or base64 encoded in an ascii file.

    > However, it does not work and I am really struggling to get
    > matplotlib to generate a plot dynamically in a
    > cgi-script. If anyone has done this successfully I would
    > really appreciate some help or a simple example. I am using
    > Windows XP and Apache 2.0.53.

Hope this helps a little -- let us know if you have any more details
on the problem you are experiencing or if you make any progress.

JDH

John,

I have reduced the python script to 4 lines which no longer includes matplotlib but it still does not work (see below). I have tried many permutations - none work. If you can get this to work, under Apache-windows. I would really appreciate knowing how. This capability would be useful for displaying images from matplotlib.

#!d:/apps/Python23/python.exe

fp = open('tmp.png','rb')
print "Content-type: image/png\n"
print fp.read()
fp.close()

Tthe script generates is:

The image �http://shook-m2/cgi-bin/plot.py� cannot be displayed, because it contains errors.

plot.py is the name of the script, tmp.png is a png in the cgi-bin directory.

I am using:
Python 2.3 (Enthought version)
Apache 2.0.53
Windows XP Sp2

The script is in cgi-bin. Other python scripts work fine e.g. hello world.

Cheers, Simon

John Hunter wrote:

···

"Simon" == Simon Hook <simon.j.hook@...369...> writes:
           
   > Hi, The code below when run from a file in the cgi-bin
   > directory should generate a plot but it does not work:

It would help to have more information. What do you mean "does not
work"? Are there any errors displayed to the terminal or apache
logs. I know people have used mpl with apache, but it can be a little
tricky to get all the data paths set up properly.

matplotlib uses a couple of environment variables to find it's data
and store cache information. For example, if your fonts and
.matplotlibrc are in a nonstandard place, you need to set the env var
MATPLOTLIBDATA to point to them. Also, mpl tries to create a cache
file .ttffont.cache in your HOME dir by default, and in an apache
config HOME may not exist or may not be writable. If there is no
HOME, matplotlib will fall back on the MATPLOTLIBDATA dir, so make
sure env var is set, that it points to the directory that contains
Vera.ttf and the other mpl fonts, and that it is writable by the user
under which apache runs.

If you get this to work, please write a HOWTO and submit it to the list.

   > #!d:/apps/Python23/python

   > import sys import matplotlib matplotlib.use('Agg') from
   > pylab import *

   > plot([1,2,3,4])

   > #print "Content-type: text/html\n\n" #print "<html>Hello
   > world!</html>"

   > print "Content-type: image/png\n\n" > print savefig(sys.stdout)

This looks wrong. Doing

print savefig(sys.stdout)

will also print the return value of savefig, which is None I believe.
I think you just want

savefig(sys.stdout)

But I can't vouch for the overall approach (setting the content type
and then dumping in a binary stream of the png). It may be correct,
but I haven't used it. Somehow I would expect the stream to be mime
or base64 encoded in an ascii file.

   > However, it does not work and I am really struggling to get
   > matplotlib to generate a plot dynamically in a
   > cgi-script. If anyone has done this successfully I would
   > really appreciate some help or a simple example. I am using
   > Windows XP and Apache 2.0.53.

Hope this helps a little -- let us know if you have any more details
on the problem you are experiencing or if you make any progress.

JDH

John,

Below is a version of the script that works. The problem is windows does not put out binary. The example in the matplotlib documentation should be updated to point out this machine compatibility issue unless someone knows a better way.

#!d:/apps/Python23/python

import os, sys, msvcrt
from pylab import *

plot([1,2,3,4])

print "Content-type: image/png\n"
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
savefig(sys.stdout)

Best wishes, Simon

Simon Hook wrote:

···

John,

I have reduced the python script to 4 lines which no longer includes matplotlib but it still does not work (see below). I have tried many permutations - none work. If you can get this to work, under Apache-windows. I would really appreciate knowing how. This capability would be useful for displaying images from matplotlib.

#!d:/apps/Python23/python.exe

fp = open('tmp.png','rb')
print "Content-type: image/png\n"
print fp.read()
fp.close()

Tthe script generates is:

The image �http://shook-m2/cgi-bin/plot.py� cannot be displayed, because it contains errors.

plot.py is the name of the script, tmp.png is a png in the cgi-bin directory.

I am using:
Python 2.3 (Enthought version)
Apache 2.0.53
Windows XP Sp2

The script is in cgi-bin. Other python scripts work fine e.g. hello world.

Cheers, Simon

John Hunter wrote:

   > Hi, The code below when run from a file in the cgi-bin
   > directory should generate a plot but it does not work:

It would help to have more information. What do you mean "does not
work"? Are there any errors displayed to the terminal or apache
logs. I know people have used mpl with apache, but it can be a little
tricky to get all the data paths set up properly. matplotlib uses a couple of environment variables to find it's data
and store cache information. For example, if your fonts and
.matplotlibrc are in a nonstandard place, you need to set the env var
MATPLOTLIBDATA to point to them. Also, mpl tries to create a cache
file .ttffont.cache in your HOME dir by default, and in an apache
config HOME may not exist or may not be writable. If there is no
HOME, matplotlib will fall back on the MATPLOTLIBDATA dir, so make
sure env var is set, that it points to the directory that contains
Vera.ttf and the other mpl fonts, and that it is writable by the user
under which apache runs.

If you get this to work, please write a HOWTO and submit it to the list.

   > #!d:/apps/Python23/python

   > import sys import matplotlib matplotlib.use('Agg') from
   > pylab import *

   > plot([1,2,3,4])

   > #print "Content-type: text/html\n\n" #print "<html>Hello
   > world!</html>"

   > print "Content-type: image/png\n\n" Simon> print savefig(sys.stdout)

This looks wrong. Doing

print savefig(sys.stdout)

will also print the return value of savefig, which is None I believe.
I think you just want

savefig(sys.stdout)

But I can't vouch for the overall approach (setting the content type
and then dumping in a binary stream of the png). It may be correct,
but I haven't used it. Somehow I would expect the stream to be mime
or base64 encoded in an ascii file.

   > However, it does not work and I am really struggling to get
   > matplotlib to generate a plot dynamically in a
   > cgi-script. If anyone has done this successfully I would
   > really appreciate some help or a simple example. I am using
   > Windows XP and Apache 2.0.53.

Hope this helps a little -- let us know if you have any more details
on the problem you are experiencing or if you make any progress.

JDH

--

+++++++++++++++++++++++++++++++++++++++++
Simon J. Hook, MSc, PhD
Jet Propulsion Laboratory MS 183-501
Pasadena, CA 91109
Office: 818-354-0974
Fax: 818-354-0966
Email: simon.j.hook@...369...
http://asterweb.jpl.nasa.gov
http://masterweb.jpl.nasa.gov
http://laketahoe.jpl.nasa.gov
+++++++++++++++++++++++++++++++++++++++++