In the United Kingdom (at least) many jurisdictions employing crime analysts, either in policing or in related roles (i.e. Community Safety Partnerships/CSPs), began to do away with commercial licences for GIS software. This was certainly the case for many community safety teams across England and Wales as austerity measures saw councils reduce overheads.
Unlike the US, whereby ArcGIS seems to have cornered the law enforcement market, the UK was a patchwork of MapInfo, Arc and Northgate in policing. In some areas, CSP analysts moved to lower-cost desktop and web mapping options such as Cadcorp, Maptitude and Earthlight/StatMap. Others ventured towards open-source desktop software like QGIS.
Between 2017-2019, I found myself having to move to QGIS after having spent over a decade using commercial GIS desktop software. I learned to use QGIS for strategic, tactical and other forms of crime and public safety analytics in government and policing roles. To date, as far as I am aware, there is little in the way of guidance about what QGIS offers to police and public safety analytical roles. This article aims to highlight the functions available along with brief examples of how to apply them with crime analysis in mind.
This is not intended to be an exhaustive guide.
I will explore a variety of techniques detailed Understanding Crime: Analyzing the Geography of Crime, by Spencer Chainey, and how you can apply them in QGIS. This book is the perfect resource for anyone wishing to develop skills in geographical crime analysis. Some content is also available in open-access publications by Spencer Chainey, including Examining the extent to which hotspot analysis can support spatial predictions of crime. I signpost to both throughout this page. I also highlight additional functions in QGIS that are useful for crime analysis work.
Section 2 covers set-up (including a short quick start and the common mistakes that waste time).
Section 3 links to sample datasets so you can replicate the examples.
Section 4 covers descriptive spatial statistics (basic pattern tests and distance measures).
Section 5 covers hotspot mapping options (from simple concentration to KDE, Gi*, and DBSCAN).
Section 6 covers temporal stability, risky facilities, location quotients, and near space-time clustering (ST-DBSCAN).
Section 7 covers simple ways to map changes over time and build atlases.
Sections 8–9 cover a few extra tools and installing Python packages for plugins.
To download and install QGIS, I recommend choosing the most recent Long Term Stable Release (LTR). The download page states what the current LTR release version is called. This guide is relevant up to version 3.34.7 (Prizen).
https://www.qgis.org/en/site/forusers/download.html#.
NB: Plugins may need additional work to install on the most recent versions which move to Qt6 (see https://blog.qgis.org/2025/04/17/qgis-is-moving-to-qt6-and-launching-qgis-4-0/)
Whilst QGIS has a large number of processing toolboxes and functions built-in (core features), there are a few additional plugins that are required for using QGIS as crime analysis software. These can be downloaded via 'Plugins > Manage and Install Plugins...'.
Plugins mentioned on this page:
H3 Toolkit - nested Uber hexagons (see Section 9 for dependencies)
Multi Ring Buffer
QuickOSM - download Open Street Map data with query builder
Spatial Deviational Ellipses
Visualist - spatial point pattern functions for crime analysis
See documentation and manuals for QGIS here https://docs.qgis.org/3.28/en/docs/index.html
There are many online courses to get you started with QGIS. I have completed and can recommend the following as being extremely informative:
Map Academy: get mapping quickly with QGIS https://www.udemy.com/course/mapacademy/
Map Academy: taking QGIS to the next level https://www.udemy.com/course/map-academy-taking-qgis-to-the-next-level/
QGIS 3.XX LTR for GIS Professionals https://www.udemy.com/course/qgis-for-gis-professionals/
Alasdair Rae (Map Academy) also blogs mapping guides and shares techniques via Twitter and YouTube. @undertheraedar and @automaticknowledge.
I have provided sample datasets below:
Jack the Ripper sample datasets, link to DropBox. This data is for sections 4.1 and 4.4.
Cambridge UK built-up area data, link to DropBox. This data is for sections 4.2, 4.3, 5.1-5.7, and 6.1-6.4.
Cambridge solutions, outputs with saved symbology, link to DropBox. These are map outputs for sections 4.2, 4.3, 5.1-5.7, and 6.1-6.4.
New York Police Department dataset, link to DropBox. This data is for sections 7.1 and 7.2.
Other open datasets are listed towards the bottom of the Online Resources page.
Note on formatting: Function names and drop-down menu options in QGIS are shown like this: 'Vector > Analysis Tools > Mean coordinate(s)...'
First, we look at QGIS functions that can be used to examine general spatial patterns in your data. These consider:
Spatial behaviour of offenders (how an individual offender operates within relatively short distances)
Spatial autocorrelation (how much crime in one area is similar to nearby areas)
Testing whether hotspots are present (are the crime points clustered?)
What it is: Spatial mean (SM) is the mean centre of your point distribution. SDE describes the spread and direction around that mean.
When to use it: To show how a series changes over time, or whether incidents are dispersing / narrowing.
How to do it:
SM: 'Vector > Analysis Tools > Mean coordinate(s)...'
SDE: install the plugin tool, then use 'Vector > Standard deviational ellipse'
Quick checks:
If the ellipse looks distorted, check CRS (work in metres).
If you are comparing time periods, keep the same map extent and symbology.
Spatial mean and standard deviational ellipse, Jack the Ripper offences (QGIS). Spatial mean shows the changing anchor points as the series progresses.
What it is: A way of testing whether high (or low) values cluster in space. Moran’s I is one common output.
When to use it: When you want to move beyond “it looks clustered” and test whether there is spatial structure.
How to do it (one practical workflow):
Create hexagons in your boundary using 'Processing Toolbox > H3 > Create H3 grid inside polygons' (pick a resolution).
Count points in polygons using either:
'Vector > Analysis Tools > Count points in polygon(s)...', or
Visualist 'Choropleth Map' (often faster).
Run Visualist 'Spatial Autocorrelation Map' and select Moran’s I outputs.
If needed, filter to statistically significant areas (e.g., p ≤ 0.05).
Moran's I Cambridge criminal damage offences (QGIS). Filtered to show only those hexagons with p value <0.05, highlighting significant hot and cold spots.
Efficiency tip (repeatable workflows): If you will run this often, chain steps using the Graphic Modeler, or export your Processing History / model to Python. Batch Processing is useful if you want to run the same workflow for multiple districts.
What it is: NNI compares your point pattern to random variation. Values below 1 indicate clustering, around 1 suggests random, and above 1 suggests uniform spacing.
When to use it: As a quick sense-check: do you have enough points (and enough days of data) before you start hotspot mapping.
Important limitation: QGIS NNI is useful, but treat it as a guide rather than a definitive test (it is not as flexible as some other implementations).
Above: Example of point distribution at NNI intervals
How to do it: Using 'Vector > Analysis Tools > Nearest neighbour analysis...'
Example output using Cambridge Criminal Damage dataset shown in image.
Above: NNI output Cambridge criminal damage offences (QGIS)
What is it: Journey to crime (JTC) is the distance between an "anchor point" (i.e. a home address) and offence locations.
When to use it: To understand how far offenders travel for different offence types, and to compare distributions between groups. Opportunities seized by offenders on average tend to be more frequent within shorter distance journeys. The important principle here is that if crime increases in a small area, it is more likely that those involved live locally.
QGIS example, Euclidean and Network Distance between Jack Ripper anchor point and offences
Distance types:
Euclidean (straight line)
Manhattan (grid-based)
Network (street network shortest path)
How to do it in QGIS:
Network distance: 'Processing Toolbox > Shortest Path (point to point)' (requires a street network layer). QuickOSM Plugin (YouTube walkthrough on QuickOSM) can be used to download street data.
Euclidean distance: 'Processing Toolbox > Distance to nearest hub (points)'
Distance matrix: 'Processing Toolbox > Distance Matrix' (returns a long table).
ORS Tools Plugin - open route service, API required. An online tutorial is available here.
Quick Checks:
Be explicit about what the anchor point represents (home, last-known address, place of work, etc.).
If results look implausible, check CRS and whether your network layer is routable.
Next, we look at QGIS functions that can be used to analyse spatial point patterns and identify places with higher relative crime concentration in your study area. This is where the unit of analysis and parameter choices matter most.
Here we highlight options available in QGIS to perform:
Crime concentration
Hot Routes
Kernel Density Estimation
Choropleth and Grid Maps
Getis Ord GI*
Sampling raster values for composite maps
DBSCAN
What it is: A way of showing how much crime sits in a small number of micro-places (street segments, small grids, etc.).
Why it matters: A large body of research finds that a high proportion of crime sits in a small proportion of micro-places (often framed as 25–50% of crime in <5% of places).
How to do it (practical steps):
Aggregate points to micro-units (street segments, grids, hexagons)
Rank-order units by count (highest to lowest)
Calculate % of total and a running cumulative %. This can be done in the attribute table / field calculator in QGIS, or exported to a CSV for Excel/Sheets
Output: This lets you define cut-offs (e.g., “top 25% of crime places”) and map them.
Crime concentration table data, Cambridge acquisitive crimes, QGIS. The street segment with the highest count had 169 crimes (1.19% of all acquisitive crimes).
Top 25% and Top 50% crime street segments, Cambridge acquisitive crime (QGIS)
Top 25% and Top 50% crime micro-grids of 125m, Cambridge acquisitive crime (QGIS)
Combined map showing Top 50% crime segments and Top 50% micro-grids (QGIS)
Acquisitive crime in Cambridge, number of crimes per 100m
What it is: Hot routes are hotspots mapped along street segments rather than across areas.
When to use it: When street context matters operationally (patrol routes, linear retail streets, night-time economy areas).
How to do it (high level):
Build or load a street segment layer, then count points to segments (point-to-line association).
Rank segments and map top X%.
With Visualist, requiring a street network layer and points dataset, use 'Graduated Lines Map' or 'Graduated Lines Segment Map'
Quick checks: Decide how to handle incidents at junctions and in large sites (car parks, malls).
What it is: KDE creates a smoothed surface showing relative intensity of points.
When to use it: When you need a quick, intuitive hotspot surface for briefing. It is also useful as a comparison layer against more structured outputs.
How to do it: Use 'Heatmap (kernel density estimation)' (Processing Toolbox).
Key parameters:
Cell size (resolution)
Bandwidth / radius (smoothing)
Weights (optional, for example, using crime harm scores)
Quality checks:
If the surface looks “wrong”, check CRS (metres) and bandwidth units.
If you change bandwidth, rename the output layer so you can track what you did.
Criticisms:
Lacking a universal consensus on the parameter settings
Visual allure can lead to validity and statistical robustness being overlooked.
Caution on parameter settings. Each map shows the same data with different parameter settings
Suggested routines for parameter settings (simple):
Generate a bounding box for your study area using 'Bounding boxes'.
Measure the shorter side of the study area bounding box. Use the Measure Line icon on the QGIS ribbon (or shortcut key Ctrl+Shift+M). Our Cambridge BUA study area is 11,809 metres.
Divide this value by 150 and multiply by 5. 11809 / 150 = 78.7 (cell size/resolution). 78.7 * 5 = 393 (bandwidth/radius).
KDE Hotspot central Cambridge violence and sexual offences (QGIS)
KDE Hotspot harm-weighted (pseudo harm values) central Cambridge violence and sexual offences (QGIS)
What it is: Counts (or rates) aggregated to polygons (neighbourhoods, grids, hexagons).
When to use it: When you need a clear “where is most of it” view that is easy to reproduce.
Practical notes:
Grid sizes (e.g., 125m) can work well for micro-place patterns, but you should sanity check that they match how the area is used (dense city centre vs rural).
If you are comparing areas, rates matter. Counts alone can mislead.
Figure image from Kitchin, Lauriault and McArdle (2015) Knowing and governing cities through urban indicators, city benchmarking and real-time dashboards (see here)
How these can mislead: These maps show housing vacancy in Tallaght, Dublin. Using Electoral Divisions (1), the viewer is drawn to one large area with vacancy rates 15% to <30%. At the finer Enumerator Area (2) level, three areas stand out—including one that is completely hidden at the Electoral Division level.
Even these areas are still large and mask sharper patterns. At the Small Area (3) level, the signal becomes clear: four tightly clustered micro-places where vacancy rates exceed 30%.
If these were maps of repeat domestic abuse or burglary, maps 1 and 2 would miss one of the highest-risk areas. They would also encourage resources to be spread across too wide an area, reducing the chance of impact.
Uniform grid maps avoid some choropleth problems caused by irregular boundary size and shape, but they have limits: they can be harder to interpret and make it less obvious where to focus. See Chainey, 2014, pp.57-58.
Hexagons are increasingly used for aggregated thematic mapping; see Why hexagons?
Grid Map using 125m grids (left) and Choropleth Map using Census 2011 output areas (right) showing all violent crime in Cambridge BUA (QGIS)
How to do it:
Requires a polygon layer and a points dataset
Visualist function 'Choropleth Map' or 'Grid Map'.
What it is: A method to identify statistically significant clusters of high values (hot) and low values (cold).
When to use it: When you want hotspot areas that are less ambiguous than KDE (Gi* gives a significance signal).
How to do it (QGIS Workflow):
Aggregate points into polygons (e.g., a grid).
Run Visualist 'Grid Map' (counts per cell).
Run Visualist 'Spatial Autocorrelation Map' and choose Getis-Ord Gi* in the LISA indicator options.
Filter outputs to show statistically significant hotspots (e.g., p ≤ 0.05 and high z-scores).
Quality checks:
If you have lots of cells, be cautious about over-identifying hotspots (multiple testing is a real issue). Clip grids first to the precise study area.
Keep the same grid size if you compare time periods.
Spatial Autocorrelation Map parameter options (QGIS)
Default output using Spatial Autocorrelation Map for Getis-Ord Gi* (QGIS)
The modified output which filters statistically significant grids and high z-scores (QGIS)
QGIS outputs: the default produces a graduated values map whereby the Gi* statistic has been converted to and displayed as z-scores.
We can filter the default output to isolate only those grid cells that are most statistically significant (the 'GETISORD_P' column, p value) AND possessing high Gi* statistic values above n standard deviations from the mean (the 'GETISORD_Z' column, z score).
In the modified output example, we kept only grid cells with a z-score ≥ 2.576. That cut-off may not suit every study area: if you have many grid cells, it can flag too many “significant” clusters just by chance.
A common fix is the Bonferroni correction (see Chainey, 2014, pp. 179–180). The idea is to tighten the p-value threshold to account for the number of grid cells tested.
For the Cambridge BUA example:
Total grid cells: N = 6,152
Desired overall significance level: p ≤ 0.05
Bonferroni per-cell threshold: p_cell = 0.05 / 6,152 = 0.00000812744 (≈ 8.13 × 10⁻⁶)
Convert this per-cell p-value to a z-score. Using a two-tailed threshold, the corresponding critical value is:
z ≈ 4.462 (i.e., retain cells with z ≥ 4.462 if you’re only keeping positive clusters; or |z| ≥ 4.462 if you’re testing both directions)
You can get the z-score using an online “percentile to z-score” calculator: https://measuringu.com/calculators/zcalcp/.
In practice, it can be more useful to combine techniques rather than relying on one. Examples you may wish to consider include:
Gi* significant cells with the highest 25–50% of street segments overlaid
KDE hotspots with the highest 25–50% street segments overlaid
Gi* significant cells coloured by KDE density values
GI* significant clusters (p <= 0.05 and z >= 4.462), and KDE density values (QGIS)
One method (Gi* grids coloured by KDE values):
Generate a KDE heatmap using 'Heatmap (kernel density estimation)' (creates Heatmap layer).
Create centroids from the Gi* grid: 'Vector > Geometry Tools > Centroids...' (creates Centroids layer).
Extract KDE values to centroids using 'Sample raster values' (creates Sampled layer).
Join Sampled back to the Gi* grid: right-click grid layer 'Properties > Joins', then use joined KDE values in symbology.
Quality check: Open the joined layer’s attribute table and confirm the sampled values are populated (not NULL). If they are NULL, check layer alignment/CRS and join keys.
What it is: DBSCAN finds clusters of points and labels the rest as noise.
When to use it: When you want discrete clusters rather than a smooth surface, and you are comfortable setting parameters.
Parameters:
Minimum number of points in a cluster
Maximum distance between points in a cluster
How to set them (practical approach):
Decide what a “useful cluster” means operationally (e.g., 1/month for serious violence vs 1/week for vehicle crime) and set minimum points around that.
Use NNI as one guide for distance, or run iterative tests (25m, 50m, 75m, 100m) and compare outputs.
Turning clusters into polygons (optional):
Split by CLUSTER_ID using 'Split vector layer', then buffer + dissolve to get cluster areas. Batch process this to avoid doing each cluster manually.
DBSCAN clusters of violence crimes in the north of Cambridge. Each colour represents a cluster containing a minimum of 50 points whereby the maximum distance between points is 50 metres. The gray smaller points represent random 'noise' (QGIS)
DBSCAN clusters of violence in the north of Cambridge. In this representation, the clusters are coloured according to the total number of points within them. We can use this to isolate the highest volume clusters that may be of most interest (QGIS)
DBSCAN output transformed to polygons using dissolved buffers (QGIS)
Next, we look at QGIS functions that can be used to analyse spatial-temporal data and identify disproportionality. We also look at simple methods that can be created with combined use of QGIS and spreadsheet software.
What it is: A simple measure to assess whether crime in an area is stable across time periods, or concentrated in a short spike.
What you need: A table where each row is a geographic unit, each column is an equal time period (e.g., 4-week blocks), and values are crime counts.
Why it matters: Finding areas with stable or persistent patterns of crime for prioritising.
TSI Formula (Excel-style): TSI = 1 − Σ ( (period_count / total_count)² ) across all time periods.
Interpretation:
TSI ≈ 1: crime is spread evenly across periods (stable)
TSI ≈ 0: crime is concentrated in one period (spike)
TSI data example for violence at Uber Hexagons resolution 9 (QGIS)
How to visualise in QGIS: Example showing TSI value of greater than 0.75 for the prior six time periods (representing stability) with most recent violent events overlaid. Using 'Choropleth Map' and filtering using greater than or less than (CumFreq <= 0.5 AND TSI >= 0.75).
Facilities are places with specific functions (restaurants, bars, schools, car parks, etc.). Risky facilities refer to the small proportion of a facility type that accounts for most of the crime (Eck, J and Clarke, R.V. (2007) Understanding Risky Facilities. Pop Center Tool Guide No. 6.).
How to visualise in QGIS: Visualist provides 'Proportional Symbols Map'. Your data needs one point per facility with a count (or rate).
The Key Point (denominators): Counts can hide risk. Two supermarkets can have similar counts but very different floor space and very different risk when expressed as offences per 100m².
Proportional symbols map, shoplifting offences at supermarkets in Cambridge; on the left by count of offences, on the right by rate per floor space
What it is: A rate-ratio style measure comparing concentration in a sub-area (or facility) to the wider region.
One common form (area-based): LQ = (subarea_offences / studyarea_offences) ÷ (subarea_area / studyarea_area)
This can also be applied using counts of crime within distance bands (e.g., within ring buffers around pubs).
See Location Quotients.
Supermarket shoplifting offences data for Cambridge BUA
Multi-Ring Buffers around bars and pubs in Cambridge (QGIS)
Worked Example: Using 'Multi-Ring Buffer' Plugin Tool was used to draw four 100m donut ring buffers around Cambridge pubs. The area was calculated. 'Choropleth Map' was used to determine the number of violent crimes in each ring buffer. LQ calculations show that violence is 3.6x more likely within 100m of a bar/pub, and this risk decays as one moves further away from bars.
What it is: ST-DBSCAN detects clusters in space and time (space-time hotspots).
When to use it: When the operational question is “where and when is this clustering?”, rather than “where is it high on average?”
Parameters:
Minimum cluster size (how many offences should there be in each cluster)
Maximum distance between each incident point
Maximum time between points (hours/days/weeks)
How to do it: Use 'Processing Toolbox > ST-DBSCAN clustering'
The example provided shows a single cluster of violent crimes in Cambridge. Offences occurred within a relatively small area (no more than 100m between each point) and a short timeframe, 27th August to 6th September.
Viewing results of a ST-DBSCAN and a docked table with the crime details for this cluster (QGIS)
Using basic maps to visualise performance data can be done quickly in QGIS, provided the data is organised in a wide format (columns for periods). If you need pivot-style tables in QGIS, the GroupStats Plugin can help.
A simple approach is to calculate change fields directly in the Layer Properties value expression and label areas by the change. The example shown compares one year to the previous year and labels precincts by the difference for Precincts in the New York borough of Brooklyn.
How to do it: In the Layer Properties dialogue box, within the Value box, specify a calculation. This examples uses the 'Poisson e-test' to show significant changes (see Testing changes in short-run crime patterns.).
Atlases are useful when you want the same layout repeated for many areas (districts, wards, neighbourhoods, such as Compstat style maps). Build one print layout, then generate pages automatically. For those familiar with ArcGIS Pro, this is similar to 'Data Driven Pages'.
Screenshot of a simple QGIS Atlas for shootings events by precinct using QGIS Print Layout
If you need charts from your data in QGIS, the Data Plotly plugin provides basic chart types (bar charts, boxplots, histograms, scatter plots). Charts update based on map view or selected features. This is useful if you want quick “time of day / day of week” charts for a hotspot or selected area, and to embed those visuals in a print layout.
2D Histogram Chart showing the volume of offences by day and hour across Cambridge (QGIS, Data Plotly)
Bar and histogram showing the volume of violent crimes in central Cambridge by day and hour (QGIS, Data Plotly)
To add open-source base maps in QGIS, you can use:
QuickMapServices plugin (see video guide here),
Python Console (see here for how to guide),
or by manually adding using XYZ Tiles on the Browser Panel.
How to add manually: Right click on the XYZ Tiles option in the Browser Panel. From here name the connection (i.e. Bing VirtualEarth) and add the URL (http://ecn.t3.tiles.virtualearth.net/tiles/a%7Bq%7D.jpeg?g=1).
URL and Min/Max Zoom levels are available in the code section of the following page.
Some plugins require Python packages that are not installed by default. One method is to use the OSGeo4W Shell / QGIS environment and install via pip (e.g., pip install pandas). If installs fail, install one package at a time.
Useful plugins and packages listed on this page include:
Cluster Analysis (k-means and hierarchical) requires pip install scikit_learn numpy pandas *may need to install one at a time*
Density Analysis requires pip install h3
H3 Toolkit requires pip install h3
Spatial Analysis Toolbox requires pip install pandas geopandas libpysal esda mgwr *may need to install one at a time*
How to do it: Navigate to the QGIS folder from the Windows Start bar applications menu. Within this folder you will see OSGeo4W Shell. Right-click on the icon and select the option to Open file location.
Then right-click OSGeo4W Shell and select the option to Run as administrator. Select Yes when the dialogue box appears, and then the Administrator: OSGeo4W Shell will open and you will be ready to add the packages from the command line.
Assuming you only have one version of QGIS installed, the command line should display the directory of your QGIS (C:\Program Files\QGIS 3.28.12>). To navigate the directory upwards use cd.. and downwards use cd Folder Name. Alternatively, you can first type o4w_env to take you to the directory needed to install packages.
Chainey S (2021) Understanding Crime: Analyzing the Geography of Crime, ESRI.
Chainey S (2013) Examining the influence of cell size and bandwidth size on kernel density estimation crime hotspot maps for predicting spatial patterns of crime. BSGLg, 60: 7-19 https://core.ac.uk/download/pdf/16219377.pdf Accessed 13.08.2023.
Chainey S. and Ratcliffe J. (2005) GIS and Crime Mapping, Wiley.
Eck, JE; Chainey, S; Cameron, JG; Leitner, M and Wilson, RE (2014) Mapping Crime: Understanding Hot Spots. National Institute of Justice. https://www.ojp.gov/pdffiles1/nij/209393.pdf Accessed 13.08.2023.
Harries, K (1999) Mapping Crime: Principle and Practice. National Institute of Justice. https://www.ojp.gov/pdffiles1/nij/178919.pdf Accessed 13.08.2023.
Weisburd D (2015) The law of crime concentration and the criminology of place. Criminology 53(2):133–157
This page was updated on 09/01/2026