QGIS 2 2025: Analyzing geographic data
Nicar25, Minneapolis
John Walton and Daniel Wainwright, BBC News

Links


  • Download QGIS here. Please use the Long Term Release (LTR) version. This tutorial works with LTR 3.34 or 3.40.

The aim


Build on your existing knowledge of QGIS and learn how to explore, manipulate and analyse geographic datasets to gain new insights.

This session is good for: 

Those who attended the QGIS 1 workshop or those who already know the basics of visualising geographic data in QGIS.

These are the full follow-along instructions from the NICAR session with a worked example.

Premise


Which neighbourhoods of Minneapolis have the most fires? And how close are the fire stations in Minneapolis to the emergencies they have to respond to?

This tutorial will cover how to analyse geographic data in different sources, even when there’s no common column to join them with - something our work in QGIS 1 depended on.

We’ll also look at how far away the fire stations of the city are from the emergencies they responded to in one year.

Setup


If you’re not on a NICAR laptop, you will find the data and shapefiles here - please download and unzip them before starting (go to the green Code button and download as zip).

Once you have them and have unzipped, we want the folder called QGIS2. 

This includes a QGIS project that’s already been set up with our starting data in. Open QGIS and open the project (called minneapolis_fires_start.qgz).

You should see a map like this of Minneapolis’ neighbourhoods but don’t worry if it’s just blank at first

If you aren’t seeing this map, then click on the zoom to full view icon, which is the one at the top that looks like a magnifying glass with three arrows coming off it.

There are 3 data sets pre loaded - see the layers pane on the left hand side of your screen

  • Minneapolis_Neighborhoods - These are the different areas of the city we’re going to start with, they’re the grey polygons on our map
  • Fires_Confirmed_2023 - The red dots are the fires responded to and where they took place. The underlying data also tells us the number of the fire station that led on it as well as some categories of incident
  • fire_stations_projected - Latitude and Longitude of each fire station in the city, represented by blue dots

At the bottom, our projection should already have been set as EPSG:26915.

You may remember from our first session that this means our maps are shown the way they’re meant to look on the globe. It’s important that all the layers in this have the same projection, otherwise we could end up with our fire stations in Minsk instead of Minneapolis.

There’s an unchecked layer called OSM Standard. Ignore that for now, we’ll get to it later.

1. Which Minneapolis neighbourhood had the most fires in a single year?


We have a lot of fires throughout the city, represented by the red dots on our map, particularly around the centre. It’s not practical, or desirable, to count them by hand, so instead we can get Qgis to do it for us.

QGIS can count up the number of fire dots inside each polygon of our neighbourhoods map - so this is how we can go about answering our initial question; which neighbourhood had the most fires?  

Go to the Vector menu > Analysis Tools > Count Points in Polygon


In the Polygons box, we’re going to choose our Minneapolis_Neighborhoods layer, because we’re counting the number of dots in each of those.

Our Points will be our Fires_Confirmed_2023 data.

Count field name has been populated with NUMPOINTS. This is what has been selected for us as our new column name. We’re counting the number of points. You could call it something else if you want to.

Click Run.





We now have a new layer called Count.

You might find it has appeared on top of your map or it might be underneath some of the existing dots. It all depends on where it’s appeared in your layers pane. Drag whichever layer you want on top to the top of it.


**Save your project**

We’ll uncheck all our other layers now and take a look at our attribute table for our new Count layer. Right click on Count and select Open Attribute Table.

We have our new column called NUMPOINTS that isn’t in the attribute table for our Minneapolise_Neighborhoods layer.

If we click the column header NUMPOINTS twice, we sort it in descending order.


There’s one area where 84 fires occurred during 2023, the Whittier neighbourhood.


Showing them on the map


Let’s make our map a choropleth with our new data. This will be hopefully familiar to you if you did our first session.

Firstly, we’ll dock our Count layer attribute table to the map. That’s the last clickable icon on the right at the top of the table.

Double click on our Count layer, choose Symbology and change Single Symbol to Graduated.

Choose NUMPOINTS as the Value.

Change our mode to Pretty Breaks and click Classify.

Now if we click Apply, we’ll get our map.
We can also put our labels of place names on. 

You can do this by double clicking and choosing the labels option, but for many regularly used functions there’s a shortcut at the top, along the toolbar.

Click the abc icon at the top of the map and open Layer Styling
Change the dropdown from No Labels to Single Labels.


It’ll be really cluttered, but right now we’re concerned more with looking for our story and doing our journalistic research into which neighbourhoods had a lot of fires.

If we want to label just the areas with the most fires, those with the deepest red, we can do that.

Double click on the Count layer again and in Symbology, click the Histogram and Load Values.



We can see from this and our breaks over in the layer that the most fire-hit neighbourhoods had between 60 and 80 and 80 to 84 fires in 2023.

Click cancel to close the histogram and then in the Layer Styling, change the dropdown from Single Labels to Rule-based Labelling (you can repeat the step above if you’ve already closed this)

If there is something in the box already saying “(no filter)” then click on it to highlight it and click the red minus (-) icon to remove it. If there’s nothing there then carry on to the next step.

Click the green + icon at the bottom

Then by the Filter header, click the 
Go to Fields and Values, double click on NUMPOINTS and click OK. Then put the greater than symbol ( > ) and type 60. 


Remember also to choose your styling. When labelling a map like this, it’s worth having a buffer around the text so that it’s shown against some white, to help it show up properly against deeper colours.

You can do this by changing the font size to 18 and then clicking the fuzzy blue abc and checking draw text buffer.

If we dock the attribute table of the Count layer and sort on the last NUMPOINTS column you’ll see we’re highlighting the areas with the most fires.


The default red here also isn’t great. The notes from our previous session tell you a bit about how to change the colours.

But what we gain from this is an understanding of the neighbourhoods where fires happened most. This can lead us towards further stories about why this might be

Or we could use QGIS to dig deeper, to see what else may be happening.



**Save your project**

2. How far were these fires from help?


Let’s uncheck our Count layer now and re-check our original neighbourhoods and fire stations projected layers. 

If you’re using the pre-loaded layers you’ll see the fire stations are in blue. You can uncheck the fires to see them on their own.



Now, let’s just imagine, purely for the purposes of our workshop, that for a fire station ought to be no more than a mile away in order to respond to an emergency.

What does a one-mile radius of each fire station in Minneapolis look like?

To find out, we need to create a Buffer layer.

Buffer zones are really useful. You can analyse areas around specific points and you can use them to see patterns that might otherwise be missed.

Let’s say your audience has been getting in touch about pollution coming from some industrial area nearby and you’ve got some air quality data you want to investigate to see if there’s a connection.

Or maybe you‘ve got a dataset of rent or house prices and you want to see whether they’re more expensive near to Metro stations. 

Or maybe there has been a rise in thefts and muggings, and someone’s told you it’s concentrated in a particular area and you want to test the theory.

In this example, we’re looking at one aspect of how far emergencies happened from the service that responded to them. 

OK, let’s have a go.

Go up to the top and click Processing >> Toolbox.

In the menu that opens up, search for Buffer and double click it



We’ll select our fire_stations_projected as our input layer.

We want the distance in miles and we’ll just have 1.

We can increase the number of segments to 10. The more segments, the smoother the buffer will be.

Hit Run and then when it’s finished, click Close





Now we need to change the styling so we can actually see where our fires were.


Re-check our Fires_Confirmed_2023 layer.

You can see there’s a number of fires outside of our circles.

Then on our new Buffered layer, let’s double click and open up our Symbology menu.

First, we’re going to scroll down in the window to outline blue and select that and apply.

You can change the colour if you want to, but you need to select the outline first. 

Here we can now see all the fires and whether they fell within a one-mile radius of a fire station.

You may have noticed down towards the bottom we’ve a few dots that don’t appear on our neighbourhood map. These are fires that happened outside of the city’s neighbourhoods. The one at the bottom was somewhere between the airport and Fort Snelling golf course.


Save your project


3. Finding fires inside and outside our buffer zones


Go to the Processing Toolbox and search Select by location

We’re going to select features from our Fires_Confirmed_2023 layer and check ‘are within’ and then choose our Buffered layer.

This is going to highlight the fires that are within our 1-mile buffer zones

The map has changed the dots accordingly


And in the attribute table for our Fires_Confirmed_2023 layer, all the fires within the buffer zones are now highlighted. If you scroll right on the attribute table, you’ll see the last column is called OBJECTID. We don’t need to do anything with this, but just be aware that’s the last column currently.

We need to turn this into some new data. Click on the abacus icon to open the field calculator.

Make sure the “only update selected features” box is checked.

Call our new output field in_buffer and change the field type from Integer to Text (string).

In the Expression box, type Yes’ and make sure to only use single quotation marks.

What this will do is create a column we can filter on that says “Yes” if the fire happened within a one-mile buffer zone of a fire station, or be NULL if it was outside.
You might get an error message. Click OK anyway as it should have worked.

This adds a new column to our data attribute table for Fires_Confirmed_2023. Those that are outside the buffer zones stay as NULL.


QGIS will have put this layer into Edit mode.

You can toggle this off by clicking the pencil icon in the top left of the attribute table.

Say yes to saving it.


Go to your Fires_Confirmed_2023 layer, right click and choose Filter.

Double click on the in_buffer column name at the bottom of the Fields list.

Then type IS NULL after it.

  • We’re going to filter our data just to those fires that are not in our buffer zones.

This is because as journalists we’re looking for the stories in places that may not be being served by the authorities, or where the hard working fire department may have the toughest time getting to the people who need them.

This has now left us with a map of fires that happened over a mile away from any Minneapolis fire station.

Depending on what your story is about, this can help you to find places and areas that might not be getting the same level of help as other areas. For us, what this is showing us is the places the fire department had the furthest to get to. 


Save your project

4. How far away from a station were those individual fires?


Open the attribute table of our new filtered dataset Fires_Confirmed_2023. If you scroll to the bottom and look at the index number on the left, you’ll see we have 192 fires outside the 1 mile buffer zones of any station in the city.

We can work out exactly how far each of these 192 fires were from their nearest station and use this for analysis outside of QGIS.

One warning to mention is that QGIS will give us a straight line distance, which means that a station slightly further away might actually get there quicker than the nearest one.

Go to Processing toolbox >> Vector analysis and choose Distance to nearest hub (points).

Our source is our Fires_Confirmed_2023 layer (remember, we have this filtered).

Select fire_stations_projected as our Destination hubs layer and set the measurement unit to Miles.

Run it.

We have another new layer called Hub distance.

Open its attribute table and over on the right, you’ll see it has now a couple more columns than our filtered fires one.

HubName is the station number, taken from fire stations layer.

HubDist is the distance in miles between the fire and the closest station.

But if we scroll over to the left in the attribute table, the station recorded in the original fire data may be different.

If we sort our attribute table by HubDist, we have a fire that was 1.8 miles away from station 12 in the south east of the city, but there’s no record of the station that attended in the original data. That’s the fire down by the golf course and the airport that wasn’t on our neighbourhood map.

5. Where had the most fires over a mile away from a fire station?


Let’s see now how these 192 fires look at a neighbourhood level. We’ve used QGIS to home in on fires that are over a mile away from a station. So which neighbourhoods of the city did they happen in most? Our story is changing from a basic one about the areas with the most fires, to the areas that have the most fires the furthest from help.

We can go back up to Vector >> Analysis Tools >> Count points in Polygon.

Select our Neighbourhoods layer as our Polygons and our newly filtered Fires_Confirmed_2023 as our Points and run it.

Then we go right back to the start and create a Graduated choropleth.

Double click on the new Count layer (not the old one with the breaks already there) and in the Symbology menu, change from single symbol to Graduated.

Select NUMPOINTS as our value. 

Change the mode to Pretty Breaks and Classify. Then Apply.

Two neighbourhoods had over 15 fires each in 2023 that happened over a mile away from any fire stations.

Uncheck any layers you still have checked except the new Count.

Then we can hit our ABC button again and create a Rule based label where the Filter is “NUMPOINTS” > 15. If you have time, repeat the steps on creating a text buffer and change you font size.

Open and dock the attribute table for the new Count layer and you’ll see that these two neighbourhoods had 17 fires that were over a mile away from the nearest station.


6. A different base map


Say you want to go and actually find the places where the fires happened or show them to your audiences. Polygons of neighbourhoods don’t show us that. But you can bring in a map like this.


To get a real street-level map takes just a few clicks. 

However, on the shared wifi, this may not work for all or even any of you. So if it doesn’t, maybe have a try later. But let’s show you anyway.

Towards the top is this icon

If you click it, you can choose OSM Standard.

If that isn’t there you may need to install your plugin first, which is where the shared wifi may make us struggle.

Go to the very top, click Plugins and choose “manage and install plugins”.

You can then search for QuickMapServices.





Now go up to the web services on the toolbar. It might be hidden behind an >> symbol next to the world with binoculars icon. Choose QuickMapServices.



Choose OSM Standard.

A base map should now have appeared if it wasn’t there before.  

You can also check the OSM Standard layer that was pre-loaded into the project.


Save your project


7. And finally - saving your layers



While saving your project is vital, the changes we’ve made to our layers will also disappear if we don’t save them.

Any layers with this symbol are only temporary:



If you click on them, it opens a Save Scratch Layer box.

It’s not simply a case of adding the file name. You need to navigate to the folder on your machine where you’ve been working.

Choose the format you want to save them in. It could be an ESRI shapefile if there are things you want to work with in this format again. Or you could choose Comma Separated Values (CSV) if you want something you can look at in a spreadsheet.

Click the three dots next to file name and then navigate to the folder.

Type your chosen file name into ‘save as’. Click save and then click OK on the save scratch layer.

Do that for any layers you want to keep.

If you try to exit and get an error message about something not being saved, check before you close QGIS.