Last semester I worked with Darya Filippova, Joonghoon Lee, Andreea Olea, and Krist Wongsuphasawat on a project for Ben Shneiderman’s Information Visualization course. We took a subset of the accident data collected by the CATT Lab and built a tool to help figure out why certain stretches of road have a higher number of accidents than others. We developed a number of visualizations to achieve this goal. My major contribution was the heat map.
I’ve only seen a few Flex apps that use heat maps to show clusters of data, and I’ve never come across any source code. Corunet has a blog post detailing their server-side heat map algorithm, and I ported it to Actionscript. I’ve continued to play around with the code since the semester ended, making it more efficient, extensible, etc., and I think it’s about time it saw the light of day.
The application below traces your mouse movements, storing the x and y positions in an ArrayCollection which is fed to the heat map. The size of the collection is capped at 1000 points because I didn’t want to blow up anyone’s browser, but any machine that can actually run a web browser shouldn’t run into any problems with that many points.
You can view the source here.
The algorithm isn’t all that complex, and the functions built into the BitmapData class take care of a lot of the dirty work. Basically, a circle with a gradient fill is drawn for each point in the collection. The gradient ranges from black on the edge to blue in the center. Bluer regions represent areas that have had more “influence” than others. The exact shade of blue used in the center is dependent upon the maximum number of coincident points. As this number increases, the relative influence each point has decreases, preventing the entire heat map from being rendered as a supersaturated mass. The BitmapData’s threshold method is used to convert the black-blue image to a fully colored heat map.
The HeatMap class is driven by an ArrayCollection of Objects, and the Objects are mapped to the screen coordinates based on their x and y values if they exist. Because not everything has an x and y value, the HeatMap has a transformationFunction property which is used to project objects to screen coordinates. Also, a weightFunction property is available which allows weights to be assigned on a per-object basis. The usage of these to functions is similar to that of the dataFunction property in the charting classes.
That’s all there is to it. The source is pretty well documented, so you can get the nitty gritty details there.
Update (August 25, 2008)
I’ve added the HeatMap component to my Google Code repository, so the source shown here isn’t the most up-to-date. Rather than continually update this post when I make a change, I’ll let the most current revision speak for itself.
The HeatMap, and all of my future opensource work will be licensed under the MIT license.

11 Comments
nice work
Michael– this is very cool…I have an application I am building that this would work well for. Are you interested in doing some contract work?
Colin Cook
Michael, this work is amazing. How hard would it be for me to rewrite it without Flex? I don’t think I have time to learn Flex before my next project. I saw that the HeatMap class extends what looks like a Flex object. If you have a second please let me know your thoughts.
Trygve: The core of HeatMap is the drawHeatMap method, and that should be easy to replicate in AS3 without using the Flex framework classes. HeatMap could extend Sprite instead of UIComponent and dataProvider could be an Array instead of an ArrayCollection. You’ll lose the IInvalidating methods, but you can redraw the heat map onEnterFrame instead. If you’re not coding in AS at all, you’ll just need to replicate drawHeatMap using your language’s bitmap utilities.
Thank you so much for responding!
I hope I’m not bothering you with too many questions but I’m new to AS3 (although I have a strong programming background in Java and .NET). Can you help me understand how to render the heatBitmapData to the stage? I noticed the overloaded methods [commitProperties()] and [updateDisplayList()] however I’m assuming those are part of the UIComponent class. (I just removed the override).
I added a few lines to the constructor of HeatMap to create some points in my array and replaced the _dataProvider with this points array in commitProperties(). Then I simply tried to call the commitProperties() and then the updateDisplayList() which in turn calls the drawHeatMap() method.
The fla compiles fine but I don’t think I’m adding anything to the stage (just a blank white stage when I debug). I thought I would need an addChild(…?) to add it to the display list. I only want to run through the points and display the map once (meaning I don’t need to do it to loop on an enter frame event).
I hope I’m doing a good enough job explaining myself. I could provide the source changes I made if that would help you understand my question. I know how difficult and time consuming it can be to try to help every person who may contact you so I understand if you’re unable to assist me.
Any help you can provide will be greatly appreciated. Thanks.
I found my error. In the updateDisplayList() method, the following line [graphics.drawRect(0,0,width,height);] always contained zeros for height and width so the drawHeatMap() never made it through your first if statement. I had to hardcode the width and height for some reason. I tried stage.height & stage.width but that didn’t work but I can figure that out later.
However, I have a new question for you
. I’m afraid I may not be able to use this example after all. Is there a way to allow this heat map to be semi-transparent over an image. I’m assuming that I need to start with the underlying image as part of the bitmap before I start the processing of the points…? Am I heading in the right direction? I feel like a kid swinging blindly at a piñata.
Again, thanks for any help you may provide. I promise I’ll stop spamming your blog soon.
This is wonderful, thanks for posting the source! I might try to use this to do some realtime data viz.
Thanks
Thank you for sharing the source. Your implementation is amazing. I noticed some performance degradation with larger canvases, but thats to be expected with the amount of points being drawn. I am curious as to the format used for the Gradient dictionary arrays. I’ve never seen colors mapped that way before. How did you come up with those values? Fireworks? Photoshop? Thanks and keep up the great work.
Shawn: This is something that a few people have asked about, so I should probably write up a post about exactly how it works. Basically, the HeatMap needs 255 exactly colors, so it just felt more natural to pre-generate the array than calculate them on the fly. To create the arrays, I built a few linear gradients, drew them to a BitmapData that was 255 pixels wide, and extracted the color at each pixel.
It would be interesting to extract that technique into a class that could generate random gradients, or better yet, take the algorithm and allow the user to define their own.
Again, thanks Michael!
Thanks Michael for this great work! I’ve created a simple tool to draw the gradient by hand, and use your process to create the gradient array…
http://isokon.net/post/gradientArray/accessColorInGradient.fla