Behind the scenes

Behind the scenes: Making a heatmap of gun seizures


On Wednesday we released Sea of Steel, an interactive graphic that shows guns recovered in D.C. and Prince George’s County from 2000 to early 2013. Police confiscate guns from crime scenes, find them discarded on playgrounds and under cars and collect them through amnesty programs. Since 2000, police have seized nearly 50,000 guns in these two jurisdictions.

This project began with data on 46,800 guns seized or recovered by police and sent to firearms examination units in the District and Prince George’s County from 2000 through early 2013. Using primarily Perl, SAS and ArcMap, database editor Ted Mellnik geocoded addresses of gun recoveries, analyzed patterns and created static maps for us to use as reference and in the intro video. Here’s what he had to say about the process:

The unique addresses in the gun data were geocoded and assigned latitude and longitude values so they could be placed as dots on a map. This first map wasn’t appropriate for publication because too many dots were close or on top of each other, and the patterns were obscured. 


So the dots were processed into a heat map that could clearly show the highest gun concentrations.

The heatmap started with a grid 1,500 cells wide covering the overall map area. To make the concentrations visible, the gun points were in effect blurred and then counted in the cells that they overlapped. The gun density value for each map cell was based on the number of guns within a distance of 0.2 mile of the cell center, with the value contributed by each gun falling off with that distance. The cells were shaded according to their total gun density value. This approach, known as kernel density analysis, is often used to generalize the distributions of points like crime locations so their patterns are more apparent.

Our grid was created in a free program called CrimeStat that can be used for kernel density and other spatial statistics.

Ted’s analysis served as the basis for our interactive heatmap, which uses MapBox to display tiles generated in TileMill. By importing a shapefile of the grid and gun recovery densities into TileMill, I could style grid cells based on the data attached to each one. TileMill uses CartoCSS, a styling language based on CSS, to control the way elements on the map tiles appear.

The screengrab below shows how I shaded grid cells based on the “dzall” attribute Ted included in his shapefile. You can also see how I created different styles based on zoom level, so users could see geography more clearly when zoomed in.


(Side note for aspiring TileMillwrights: The “polygon-comp-op” attribute, the equivalent of Photoshop’s color blend modes, works in TileMill but not MapBox interactive maps. In hindsight this seems obvious, but I discovered this the hard way.)

I uploaded these tiles to MapBox and added them as a custom layer to my base map. If you’re using mapbox.js but want the ability to toggle visibility of certain layers, you should keep your map layers separate and add them through the API. For my purposes, though, this seemed simpler.


Then I just loaded mapbox.js into my page and initialized a map using my base map ID.

The geographic queries in the map are made separate from MapBox, using data in a MongoDB database. When a user clicks a point on the map, a geospatial query including a LatLng and radius is sent to the server to retrieve data for that point.


The circle illustrating the half-mile radius is just drawn through Leaflet.js (the latest version of MapBox is now a Leaflet plugin) on an additional layer.

Check out the full project here.

- Katie Park / The Washington Post