heatmap.py: create heatmaps in python

Download:    heatmap-1.0.tar.gz

To install:
 $ cd heatmap-1.0; python setup.py install
Requires the Python Imaging Library.

Example

import heatmap
import random

if __name__ == "__main__":    
    pts = []
    for x in range(400):
        pts.append((random.random(), random.random() ))

    print "Processing %d points..." % len(pts)

    hm = heatmap.Heatmap()
    hm.heatmap(pts, "classic.png")

Highlights

heatmap() takes a list of x, y coordinate tuples and produces a heatmap describing their density. Some highlights:

Google Earth

After creating the output image, you can call saveKML() to create a KML file for Google Earth. It assumes the list of input points are a series of lat/long coordinates in decimal degrees. When loaded into Google Earth, you will see the heatmap as a Ground Overlay.

    import heatmap
    import random

    hm = heatmap.Heatmap()
    pts = [(random.uniform(-77.012, -77.050), random.uniform(38.888, 38.910)) for x in range(100)]
    hm.heatmap(pts, "classic.png")
    hm.saveKML("data.kml")

A heatmap over downtown Washington, DC:


Heatmap loaded into Google Earth
1024x1024 image, opacity 128, 150px dotsize
100 random points in downtown DC

Color Schemes

heatmap() comes with 5 color schemes:

 
classic

fire

omg

pbj

pgaitch
 
Available color schemes
Colors at the top are used for the
densest areas, the bottom the sparsest.

These color schemes are directly from gheat. (See 'credit', below) 'classic' is used by default, use another via the 'scheme' argument:
    hm = heatmap.Heatmap()
    hm.heatmap(pts, "fire.png", scheme='fire')

Details

heatmap() has only two required parameters:

There are several optional parameters, with reasonable defaults:
     |  heatmap(self, points, fout, dotsize=150, opacity=128, size=(1024, 1024), scheme='classic')
     |      points  -> an iteratable list of tuples, where the contents are the
     |                 x,y coordinates to plot. e.g., [(1, 1), (2, 2), (3, 3)]
     |      fout    -> output file for the PNG
     |      dotsize -> the size of a single coordinate in the output image in
     |                 pixels, default is 150px.  Tweak this parameter to adjust
     |                 the resulting heatmap.
     |      opacity -> the strength of a single coordiniate in the output image.
     |                 Tweak this parameter to adjust the resulting heatmap.
     |      size    -> tuple with the width, height in pixels of the output PNG
     |      scheme  -> Name of color scheme to use to color the output image.
     |                 Use schemes() to get list.  (images are in source distro)
Most options are self-explanatory, but dotsize and opacity could use some background.

Tweaking the heatmap output

During processing, heatmap() builds a temporary image of one point. The image is grayscale, has radius of dotsize pixels and a decreasing density from the center outwards. A single dot at the default dotsize (150px) looks like this:


A single point

The dot is placed into the output image for each input point at the translated output image coordinate. The input points are unbounded. Values between 0 and 1 work as well as values between 5600 and 930000. The smallest points are placed at (0, 0) in the output image, with the largest points at (width, height). The x and y axes autoscale independently of each other.

Dots are blended into the output image with an additive process: as points are placed on top of each other, they become darker. After all input points have been blended into the output image, the ouput image is colored based on the darkness of each pixel.

Before colorization, the sample script above builds (in memory) an intermediate output image similar to:


Before colorization
400 random points, 0 < pt < 1
1024x1024 image, 150px dotsize, opacity 255

After colorizing with the 'classic' scheme (the default), the same image looks like this:


After colorization with the 'classic' scheme.
400 random points, 0 < pt < 1
1024x1024 image, 150px dotsize, opacity 255

Appropriate dotsize is a factor of your output image size, the density of your dataset and desired results. Tweak as you see fit.

Opacity changes the transparency of the color during the colorization process. If you want to use the heatmap as an overlay, set the opacity such that you get your desired results.

Feedback

This worked well enough for my datasets, but I had to tweak the algorithm several times. If it doesn't work for your data, send me feedback (and your source data, if you can.) I'll try to get more generalized algorithms in future releases.

Credit

The technique and color schemes came from gheat. If you need a web-enabled interface to heatmaps with Google Maps, gheat is a good tool for the job. I didn't do anything original, but merely took their work and generalized it. Chad credits the definitive heatmap as his starting point. Like those projects, this project is under the MIT license.