Projections enable us to represent the earth on a flat surface. The WGS84 Geographic Coordinate System is the default projection in QGIS. This tutorial will walk through the process of creating a U.S. population density map in the Albers equal-area conic projection, a standard way of representing the United States with minimal distortion.
This tutorial will incorporate three datasets: one provided by Natural Earth, and two provided by the U.S. Census. First, download the current state administrative boundaries from Natural Earth, as well as 2017 state territories (both land and water) from the U.S. Census, listed below:
- ne_10m_admin_1_states_provinces (Admin 1 – States, Provinces)
- tl_2019_us_state (States (and equivalent))
Before we start, a brief overview of some terminology.
A datum defines the spheroidal surface to which a given set of coordinates is referenced, as well as the position of that surface in relation to the center of the earth. Examples include NAD83 (which we encountered in previous tutorials that used the NAD_1983_StatePlane_New_York_Long_Island_FIPS_3104_Feet projection), WGS84, and NAD27. For more concrete evidence of this, open up the QGIS Project menu, select Project Properties, and navigate to the CRS section. If you search for NAD83, QGIS will generate a long list of different projections referenced to the NAD83 datum.
Two datasets that were originally referenced to different datums, but which are then rendered in the same projection, will not line up.
A projection, or Coordinate Reference System (CRS), is used to describe geographic data. A projection is the set of transformations that converts a series of geographic coordinates, which are locations on a curved surface (the datum), into locations on a flat surface.
The Natural Earth state boundaries will serve as the 'empty' geography files for this project, to which we will join both U.S. Census state area measurements and U.S. Census population counts. We will be mapping the population density for each U.S. state, and will therefore need the area of each state, as well as the number of people who live in each state.
To download the data for this project, we will be returning again to the Census Data Portal. Navigate to the portal and click the Advanced Search option. Here we will select the following parameters within the Topics and Geography levels:
Topics>Populations and People>Populations and PeopleGeography>State>All States in United StatesSurveys>PEP Population EstimatesYears>2019
To filter the available datasets, do the following:
- On the left side of the
Advanced Searchwindow, and open up theTopicstab. Click thePopulations and Peoplesection, and selectPopulations and People. - Next, open up the
Geographytab, and selectStatefrom the dropdown menu. SelectAll States in United States. - Next, open up the
Surveystab. SelectPEP Population Estimates. - Finally, open up the
Yearstab. Select2019.
Once you have selected each of the above parameters, click Search.
Click the first entry to navigate to the table. This view should include a column listing the full name of every U.S. state, and entries for each state containing population estimates for 2012, 2013, 2014, 2015, 2016, 2017, 2018, and 2019. Before downloading, we will filter this view to make sure we only pull the values we need (2019 population estimates).
In the table view, click Filter to open a right panel. First, go to the Columns tab and make sure that both Geography and Estimate Date is checked.
Next, go to the Filters tab. Select Estimate Date. Choose Greater than or equals, and set the value to 11. This will filter out all population estimate years except for the one we want, 2019.
To download the data in CSV format, click the Excel button in the top bar.
Click Export to CSV. The downloaded file will be named something like PEPPOP2019.PEPANNRES-2021-02-04T174743 (note that the metadata after the . includes the date and time downloaded).
As always, there are many possible ways to transform data to fit the needs of your project. For this tutorial we will be working in Excel, or Google Sheets, to make the original file more manageable. We will reduce the dataset down to only the values we need, and then create a new column that will enable us to join the data to the Natural Earth shapefile.
- Open up the CSV (
PEPPOP2019.PEPANNRES-2021-02-04T174743.csv). The file should look something like this:
-
In order to create our map, the only data we need is state name, state ID, and population count.
- To narrow the dataset down to only these values, delete every column except for
Geography (GEO_ID),Geographic Area Name (NAME), and the last column on the right,Population (POP).
- Rename the columns to
ID,Name, andPopulation.
- To narrow the dataset down to only these values, delete every column except for
-
We will be using FIPS region codes to join the Natural Earth vector boundaries with the Census population data. The value in the
IDcolumn is a concatenated string that combines the Census table ID with individual state FIPS codes. We need to separate out the FIPS code portion of this ID so that this dataset can match up with the Natural Earth dataset, which already uses FIPS codes to identify each state. To do that, we need to create a new column that pulls only the last four characters in theIDcolumn. We will use theRightfunction in Excel to do this.- Create a new column in Excel, and name it
FIPS_ID. - In the first cell of the column, type the formula
=RIGHT(A2,4). This will pull the last four characters in theIDcolumn,A2, into the newFIPS_IDcolumn.
- After typing the formula, hit
Enter. Double-click on the bottom right corner of the cell to populate the entire column with the new formula.
- Name the file
StatePopulations.csv, and save it to CSV format.
- Create a new column in Excel, and name it
-
As in Tutorial 03, we need to create a file that describes the data types in this new CSV before attempting to import it into QGIS. We will therefore use a text editor to create a
.csvtfile.- In your text editor of choice, open a new file.
- In our CSV file, every column except for
Populationis a string. We therefore want to type, in order,"String", "String", "Integer", "String". - Save the file with the same name as the CSV file, only with the
.csvtextension:StatePopulations.csvt. It should look something like this:
-
Now we are ready to bring all of the data together in QGIS.
We will begin by importing the Natural Earth boundary data into a new QGIS project. Because we are creating a thematic map of the United States, we only need the portions of the Natural Earth shapefile that represent U.S. administrative boundaries. We will isolate these areas, join them to corresponding TIGER state boundary data, and then re-project them to a projection more suitable for a U.S.-specific thematic map.
- Open up a new project in QGIS and add the Natural Earth states and provinces data. The data is referenced to the WGS84 datum, which we can see by navigating to the
Sourcesection underLayer Properties. The definition for the layer's projection is underGeometry and Coordinate Reference System.
- Since we are creating a map of the United States, the next step is to select all states and provinces that fall within U.S. administrative boundaries. Open up the attribute table for the states and provinces layer, click the
Select features using an expressionoption, and build a query to select all features for which theadminvalue is equal toUnited States of America.
- Hit
Selectand close the query builder. Navigating back to the map, only the U.S. should be selected.
- Now, we want to re-project the United States to the Albers equal-area conic projection. The Albers projection is a popular choice for thematic maps of the U.S. Right-click the states and provinces layer, choose
Export > Save Selected Features As..., chooseESRI Shapefile, and selectNorth_America_Albers_Equal_Area_Conic (ESPG:102008)as the CRS. You may have to search for the specific projection by clicking on the small square icon next to theCRSdropdown menu.
- Name the file
US_States_Albers. Make sure to check theSave only selected featuresoption, and hitOK. - When added to your current project, the new layer will keep its current project. As a result of this, you probably see the new layer fill up the whole screen.
- Click the button in the bottom left corner to manually update your project CRS to the same projection as the new layer,
North_America_Albers_Equal_Area_Conic (ESPG:102008). - Hide or delete the states and provinces layer.
- Open up the layer properties for
US_States_Albersand navigate to theInformationtab. You should see eitherESPG:102008orUSER:#as the projection associated with this layer. (If you see aUSERstring, QGIS interpreted this as a custom, user-added projection. It should be equivalent to the one you selected.)
We need to create a new column in the attribute table of this layer to prepare it to be joined to the TIGER layer. Though we are using the aforementioned FIPS codes for each of these joins, sometimes the codes are represented in different forms. In both the US_States_Albers layer and our downloaded CSV, the FIPS code is formatted in the following way: US##. In the TIGER shapefile, however, the FIPS code is located in a column labeled STATEFP, and is formatted without US in the front of the value: ##. To facilitate our upcoming join, we will create a new column in the US_States_Albers layer with only the ## part of the US## value.
- Open up the attribute table for the
US_States_Alberslayer. - Click the abacus icon to open up the field calculator window.
- Check
Create a new field. - In
Output field name, enterJoin_FIPS. - In
Output field type, enterText (string). - In the
Expressionwindow, navigate to theStringsection in the middle panel, and select therightfunction. This will act in the same way as the function we entered in Excel. As explicated in the right panel, this function takes two values: the first is a string, and the second is a number specifying the number of characters to extract from the right side of the string. Our string will be theSTATEFPcolumn, and the number of characters will be2. This will enable us to create a new column wherein the FIPS ID,US##, will be represented as##. - Open the
Fields and valuessection in the middle panel, and selectfips. This will be the first value for therightfunction. - Next, type a comma (
,), the number2, and a closing parenthesis ()). This tells therightfunction to represent only the last two digits of the value from thefipscolumn. YourOutput previewat the bottom should represent a two-digit number. ClickOK. A new column containing the reformatted FIPS values will now appear on the far right end of your attribute table. - Before closing the attribute table, deselect the pencil icon in the top left corner to stop editing the shapefile. Click
Savewhen prompted to save your changes.
Natural Earth data does not contain official state area measurements, but the TIGER state boundaries do. On top of your newly projected US_States_Albers layer, add the tl_2019_us_state TIGER shapefile as a new vector layer. It should automatically adopt the Albers projection. If you open up the attribute table for the TIGER boundaries, you will see the columns ALAND and AWATER, which are the land and water areas in square meters for each polygon. These are the values that the Natural Earth dataset lacks. The attribute table should also include a column labeled STATEFP, which is the one to which we will join our reformatted FIPS column. We are now ready to connect the TIGER shapefile to the US_States_Albers layer.
- Open up the
Propertiespanel for theUS_States_Alberslayer. - In the left menu, select
Joins. - Click the green
+at the bottom of the window. - Under
Join layer, selecttl_2019_us_state. - Under
Join field, selectSTATEFP. - Under
Target field, selectJoin_FIPS, our reformatted FIPS column. - Check
Custom field name prefix, and enterJ_. - Click
OK.
Open up the attribute table on the US_States_Albers layer. At the far right, after Join_FIPS, you should now see a series of additional columns, each prefaced with J_. These should include J_ALAND and J_AWATER, the area measurements of each state. Success! Go ahead and hide the TIGER shapefile layer.
Now that the US_States_Albers layer is ready, we can import the CSV file and join population values to each state.
- Click the top
Layermenu, navigate toAdd Layer, and selectAdd Delimited Text Layer.... - Select the previously-saved
StatePopulations.csvfile. - Click the
No geometry (attribute only table)option. - Ensure the data looks correctly formatted, and click
Add.
- Now, double-click on the
US_States_Alberslayer to bring up theLayer Propertiespanel. - Navigate again to the
Joinssection. Your previous join to the TIGER shapefile should be listed. - Click the
+button at the bottom of the window to add a new join. - Select
StatePopulations, your imported CSV file, as the join layer. - Select
FIPS_IDas theJoin field, which is the column name for the FIPS ID in the CSV file. - Select
fipsas theTarget field, which is the column name for the FIPS ID in theUS_States_Alberslayer. - If you like, create a short
Custom field name prefixto differentiate your joined columns from the original ones.
- Click
OK. - Exit the
Layer Propertiespanel, and open up the attribute table for theUS_States_Alberslayer. Confirm that three additional fields were added to the end. - We now need to save the
US_States_Alberslayer as a new shapefile in order to retain the join. Right-click on the layer, chooseExport > Save Features As..., and name itUS_States_Albers_JOINED. Make sure the selected CRS is stillNorth_America_Albers_Equal_Area_Conic (ESPG:102008), and keepAdd saved file to mapchecked. ClickOK.
For our final print export, we will be creating a choropleth map that represents population density for each state. Now that we have joined the US_States_Albers layer to the Census data, we need to derive one more column that represents the population per km2 for the land area of each polygon.
- Open up the attribute table for the
US_States_Albers_JOINEDlayer. - Click the abacus icon to open up the field calculator window.
- Check
Create new field. - For
Output field name, enterPopDensity. - For
Output field type, selectDecimal number (real). - For
Output field length, select10, and setPrecisionto10as well. - In the
Expressionfield, we want to calculate the number of people per km2. Navigate toFields and valuesin the center panel, and double click the joined population value, which should be at the very end of the list. Because I choseJ2as my join prefix, this value isJ2_Populatfor me. - Click the
/operator. - Navigate again to the
Fields and valuessection in the center panel, and double click the land area value. For me, this isJ_ALAND, since I choseJas my join prefix. - Since
J_ALANDis in m2, but I want to calculate population density based on km2, I need to divide this value by 1000000. EncloseJ_ALANDin parenthesis and add/ 1000000. - Your final expression should read
"J2_Populat" / ( "J_ALAND" / 1000000 ). - Save your changes, and unclick the pencil icon to stop editing the shapefile.
Before visualizing our data, we need to filter out Washington D.C. so as not to skew our scale. Open the Layer Properties for US_States_Albers_JOINED, and navigate to the Source tab. Click Query Builder in the bottom right hand corner. Type "adm1_code" != 'USA-3556' to show all polygons that do not have the Washington D.C. adm1_code, USA-3556. Click OK.
Now, we are ready to apply a color scale to this column. Navigate to the US_States_Albers_JOINED Layer Properties panel, and selecting a graduated color scale for your new PopDensity column. Set your number of classes to 8. Try a few different classification methods, and notice how they differ in output. Coose the Natural Breaks (Jenks) option. Your map should look something like this:
Once you are finished with this step, adjust colors and strokes as needed. Finally, create a new print composer. Add a legend, title, explanation, source, and scale bar. Manipulate the Scale field for the map to only show the contiguous U.S. Add new layers for Alaska and Hawaii to approach a more traditional Albers view, and make sure to include a scale bar for each one so as to be transparent about any distortion. Export your map as a PDF file. Your final map should look something like this:
Upload your final (PDF) map to Canvas.
Here is an excellent piece on how choropleth maps underrepresent minorities.
Tutorial created by Emily Fuhrman for the Mapping for Architecture, Urbanism and the Humanities class at Columbia University. Edited by Brian House for Fall 2018 and Emily Fuhrman for Spring 2021.























