Creating a statistical dot density map with QGIS

Dot Density maps:

These maps display the density and distribution of a phenomena over a geographic area. The markers, usually a dot or cross, represent the occurrence or an aggregation of occurrences which are then randomly distributed across distinct regions of the map. Colours can be used to represent different classifications to add an extra dimension to the map.

The example above shows votes to remain (red) and leave (blue) the European Union in the London Boroughs. Each dot represents 100 votes and these have been randomly scattered within each borough to represent the density of votes.

The Data

For this exercise we are going to use a geopackage which contains the outlines of the London Boroughs.  The attributes of the boroughs include the number of votes to remain and the votes to leave the EU. You can download the data here:

London Boroughs EU Referendum Results

Contains OS data © Crown copyright and database right (2017)

The Method

Field Calculator

Before we can start generating the dots on the map we need to create a column with a reduced number, as there were too many votes cast to give each one its own dot. To do this we will use the field calculator to create new attribute columns with the numbers of votes each way divided by 100.

  • Right-Click on LondonBoroughEURef in the table of contents and select Open Attribute Table
  • Click on the Open Field Calculator button above the table: 
  • You will need to set up the Field Calculator as follows:

  1. Make sure the Create a new field option is selected and enter the name 100 Leave Votes.
  2. Make sure the Output field type is set to Whole number (interger) and the Output field length can be left at the default 10.
  3. The expression needs to be: “Vote_Leave” / 100 you can user the Fields and Values section to the right to make sure you get the right field names and quote marks, just double click on the field name you want.
  4. Click OK.

Now repeat this process to create a similar column for the remain votes, call the column 100 Remain Votes. The table should now look like this:

Click Save edits  then toggle out of Edit mode 

Random points


Now we have the reduced quantities we can use QGIS to randomly assign points across each area.

Select the Random points inside polygons (variable) from the Vector > Research Tools menu.

Fill in the values as follows:

  1. Although we are making a density map we are going to use the Points count Sampling strategy.  This will assign the number of points in the Number field to each polygon.
  2. Choose 100 Leave Votes to be the Number field. Don’t choose Votes_Leave or Votes as you will then be creating a huge number of points in each polygon!
  3. Set a Minimum distance of 1 – 10 (map units, metres in this example) It is good to not have the points overlapping but not essential as we will mitigate this at a later stage. If you set this too high there may not be room for all the dots in the smaller boroughs.
  4. Save your file as a new Geopackage (or shapefile if you want to). These files will be quite big so it is best not to create a temporary layer.
  5. Click Run.  It will take a while as the algorithm has to cycle through the 33 boroughs.

Once the process has finished you will have points all over the map within the boundaries of the London Boroughs.  However the new layer added will be called Random Points in the layers panel.  We will need to change this before we create a similar file for the votes to remain.

  • Right-click on Random Points in the layers panel.
  • Click Rename and change the name to be 100 leave votes.

Now rerun the Random points inside polygons (variable) for the remain votes. Use the same process as above, but use 100 Remain Votes as the Number Value, call the new geopackage Remain Dots, and finally rename the layer in the layers panel to be 100 remain votes.

The map will now look something like this:

Styling the Map

As it stands this map is rather useless, the points are all overlapping and you can’t see the leave votes as the remain all lie over the top of them. Thankfully we can use the power of QGIS to style the points in a way that makes gives equal emphasis to dots from each layer.

First let’s style the London Borough polygons so that they don’t interfere with the dots.

  • Click on the LondonBoroughsEURef in the layers panel to highlight it and then press F7 on your keyboard to open the Live Style Dock on the right side of the map.
  • Click Simple Fill at the top of the Layer Styling panel.
  • Change the Fill to Transparent.
  • Change the Outline Width to be 0.6

The Outlines will now be clear but there will be no fill colour to interfere with the dots. We can now move on to styling the points.

We need to reduce the size of the points, so the map isn’t too crowded and give them a good colour. We also need to set a blend mode to account for any over lapping points.

  1. Use the drop down menu at the top of the Layer Styling panel to change the layer to 100 Remain Votes.
  2. Click Simple Marker to reveal more options.
  3. Set the Size to be 0.6 (Millimeters).
  4. Set the Outline Style to be No Pen.
  5. Set the Layer lending mode to be Multiply
  6. Set the Feature blending mode to be Multiply
  7. For Fill, click on the colour swatch.

We want to set this as red but we want to take down the saturation. This is to allow overlapping features to have a stronger colour; either a strong red where two features in the same layer are blended or a purple where there is overlap with the blue leave dots.

By picking colours of the same intensity we have also made sure that the map has minimal bias to one colour or the other. This is also maintained by the use of the Blend modes which mix into purple and so minimise the bias where one dot may have overlapped another of a different colour.

On the colour chart:

  1. Set R(ed) to be 255 (Full) and G(reen) and B(lue) to be 0.
  2. Go up to S(aturation) and bring this down to 70% making the red lighter. You will notice that the G and B values increase to 76.

The colour now has scope to increase its intensity if it overlaps with another dot.

Repeat the process above with the 100 leave votes layer except here we are going to use blue.  Just make sure you increase B(lue) to 255 rather than R(ed) when selecting the colour.

The map will now look like this, it works at  scales between 1:200,000 and 1:400,000.  You will need to have less dots if you want to zoom out further, or more or larger dots on a more zoomed in map.

Contains OS data © Crown copyright and database right (2017)

So you should now be able to make the distinction between the largely remain voting central London compared to the periphery where voting leave was more popular, particularly in the West.


The final thing you can do to your map is add labels to the London Boroughs so you can tell which is which. With such a busy map we are going to need buffers round the text.

  1. On the Layer Styling panel, change to LondonBoroughEURef then switch to the Labels tab: 
  2. Change to show labels for this layer.
  3. Change Label with to NAME.
  4. Choose a weightier font, I have used Franklin Gothic Demi.

Next we need to work on the formatting of the text so click on the format tab:




  1. Enter a space in the Wrap on Character field.
  2. Change the Alignment to Center.

The labels will now be better placed over the boroughs, though there won’t be enough room for them all unless you are more zoomed in.


The final steps are to add a mask or buffer to the text to make it stand out over the dots.

Click on the Buffer tab to start making changes:  

  1. Click the cross to Draw text buffer.
  2. I have left the Size as 1, but you may want to change this depending on your font.
  3. Set the buffer’s Transparency to something like 33% to allow some colour to show through.

That is the end of the instructions, you should have a map that looks similar to the one below:

Contains OS data © Crown copyright and database right (2017)
Please follow and like us:

One Reply to “Creating a statistical dot density map with QGIS”

Comments are closed.