Mapping Density with Hexagonal Grids

A very common approach for mapping point density is to use heat maps. If you are aiming for a different style, give hexagonal grids a try. The workflow is very simple in QGIS:

  1. Load the point layer
  2. Create a hexagonal grid using MMQGIS – Create Grid Layer
  3. Count points per polygon (Vector menu)

I’ve applied this method to an OGD dataset of the Viennese tree cadastre containing 119,744 tree positions:

Default style: One dot per tree

Rendering tree counts per hexagonal grid cell reveals some of Vienna’s greenest spots, such as the Prater or Türkenschanzpark.

Tree density in a hexagonal grid

There’s also a printable version.

Some notes on the necessary steps:

MMQGIS – Create Grid Layer performs great. Creating the 18,400 hexagons in this map was very fast. Note though, that this tool doesn’t seem to write correct projection information to the resulting Shapefile. Therefore it is necessary to set the projection manually after loading the file.

As a result, it is very likely that the Points in Polygon tool will warn you that the point and polygon layer are not in the same projection. I ignored the warning and everything went fine. This step was reasonably fast considering the number of points (119,744) and polygons (18,400).

  1. Kurt said:


    this looks really impressive, where rich people live, there is a lot of green!


    p.s. what is a heat map , choroplethmap , where the boundaries are squares?

    • underdark said:

      Hi Kurt,
      One thing that should be noted about that data is that it only contains trees on public ground. Trees in private gardens or areas not owned by the city are not shown.
      Here you can see an example of a heatmap: It’s basically an interpolated raster.

      • Kurt said:

        Hi underdark!

        thanks for posting the link to the heatmap-demo. Can heatmaps be also done with qgis?


        p.s. despite of that the tree-cadastre only shows public green, there seems to be more (public green) in the bourgeoise parts of the city than in workingclass- parts – at least grosso modo

      • underdark said:

        Yes, if you have current QGIS Trunk installed, you can activate a “Heatmap” plugin. It will show up in Raster menu.

    • underdark said:

      Hi Bertrand,
      That map looks great. What exactly does it show? My French isn’t that good :)
      Best wishes,

      • Hi,
        I have tried to represent the rate of artificial land in this island.
        Otherwise, your blog is very interesting !
        Good luck for the future


  2. Hi Anita,

    This looks really useful.

    I’ve tried this out on a shapefile of trees I have for a local council in London but I can’t get the grid right. If I type in a value for x and y like 5 then each hexagon is twice the size of the dataset, and if I try to specify a smaller grid it says the width and height are invalid.

    Any help would be appreciated.


    • underdark said:

      Hi Tom,

      It shouldn’t be necessary to adjust CenterX, CenterY, Width and Height values if you use “Zoom to layer extent” on your point layer before starting the “Grid layer” tool. Just adjust the H/V Spacing values to make the cells smaller/larger.

      Best wishes,

      • Ahh, thank you, I got confused by the parameters I needed to change.

  3. Allfab said:


    Great post !!
    Your posts are always interesting !!

    @Tom : It’s necessary to project point layer into a diiferent projection than EPSG:4326. After reprojection, parameters should be better in the MMQGIS’s interface !!


    • underdark said:

      It’s very interesting to play with the sliders. How big are these hexagons now?

      • Each hexagon is about 40m across (rough guess). The nice thing about the hexagon approach combined with the sliders is that it can show up quite clearly where there are some really dense clusters, much better than a heat map or just a map of all the trees rendered as dots, as you say.

  4. GOwin said:

    Very nice!

    In your example what are your H/V spacing values?

    • Thanks! In this case H spacing was set to 250 m and V spacing to 288 m (calculated automatically).

%d bloggers like this: