How to make heat maps in Flex

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, though most computers shouldn’t run into any problems even with that many points.  Clicking on the heat map will clear the collection.

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.

That’s all there is to it.  The source is pretty well documented, so you can get the nitty gritty details there.

There are a number of improvements that could be made to the HeatMap class.  At the moment the dataProvider must be an ArrayCollection of Points, but there is no reason why it couldn’t be any old ICollectionView of Objects.  Like the components in the Flex charting package, the HeatMap could have xField, yField, and dataFunction properties to give the developer freedom to plot whatever he wanted to.  It would also be useful to be able to specify a weight function so points can have variable amounts of influence.  I’ll likely make these enhancements and update this post sometime in the future.

The HeatMap is licensed under the Creative Commons Attribution License.  Do whatever you like with the source code, I just ask that you keep my name on it.

Update (August 11, 2008):

The source of the HeatMap component has been updated.  It now includes logic to ignore points that fall outside bounds of the drawing area, and the new dataFunction property allows the you to specify a custom mapping from the items in the dataProvider to screen space.  Those items can also be any type you want, though the HeatMap is partial to objects that have x and y properties.

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.  I’ve made some improvements to the code as well, but rather than continually update this post, I’ll let the most current revision speak for itself.  I’ve also decided to be a little less stingy.  The HeatMap, and all of my future opensource work will be licensed under MIT.

Tags: ,

8 Responses to “How to make heat maps in Flex”

  1. Darya Filippova Says:

    nice work

  2. Colin Cook Says:

    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

  3. Trygve Says:

    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.

  4. Michael Says:

    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.

  5. Trygve Says:

    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.

  6. Trygve Says:

    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.

  7. Michael VanDaniker » Blog Archive » Heat-Mapping the Spread of WalMart Says:

    [...] Michael VanDaniker A Flex Blog « How to make heat maps in Flex [...]

  8. Michael VanDaniker » Blog Archive » HeatMap added to Google Code Repository Says:

    [...] started a Google Code repository for all of my little experiments.  At the moment it just has the HeatMap component, but — baring any unforeseen circumstances — it will soon flourish.  You can [...]

Leave a Reply