Chapter 5 Map making

5.1 Learning outcomes

By the end of this practical you should be able to:

  1. List and explain basic mapping concepts across QGIS, ArcMap and R
  2. Interpret and manipulate data from multiple sources
  3. Create near publishable static and interactive mapped outputs
  4. Evaluate and critique mapping approaches between QGIS, ArcMap and R

5.2 Homework

Outside of our schedulded sessions you should be doing around 12 hours of extra study per week. Feel free to follow your own GIS interests, but good places to start include the following:

Assignment homework

This week, complete a draft of part 1 of the assignment. The methodology might only be in draft form / initial ideas as we move to more advanced analysis in the second part of the course.

Reading

This week:

Remember this is just a starting point, explore the reading list, practical and lecture for more ideas.

5.4 Introduction

In this practical we’re going to focus on creating mapped outputs using QGIS, ArcMap and R. For fun we’re going to use data from OpenStreetMap (OSM) and Airbnb.

5.4.1 OSM

OpenStreetMap is collaborative project that has created a free editable map of the World. As users can create their own content it is classed as Volunteered geographic Information (VGI). There is a lot of academic literature on VGI, it’s advnatages and disadvantages. For an overview of VGI checkout this article by Goodchild (2007).

If you are interested in exploring the power of VGI and OSM further checkout missing maps. They aim to map missing places, often in less developed countires, using OSM so that when natural disasters occur first responders can make data informed decisions. They run events all over the world and it’s worth going to meet other spatial professionals, gain some experience with OSM and contribute to a good cause.

5.4.2 Airbnb

Airbnb is an online marketplace that connects people looking to rent homes to those seeking accomodation often over short time periods.

5.5 Data

It’s possible to download OSM data straight from the website, although the interface can be a little unreliable (it works better for small areas). There are, however, a number of websites that allow OSM data to be downloaded more easily and are directly linked to from the ‘Export’ option in OSM. Geofabrik (one of these websites) allows you to download frequently updated shapefiles for various global subdivisions.

5.5.1 OSM

  1. Go to the Geofabrik download server website

  2. Navigate to: Europe > GreatBritain > England > Greater London

  3. Download greater-london-latest-free.shp.zip

  4. Unzip the data and save it to your current folder

5.5.2 London boroughs

We’ll use our London boroughs layer again, either load it from week 1 or download it:

  1. To get the data go to: https://data.london.gov.uk/

  2. Search for Statistical GIS Boundary Files for London

  3. Download the statistical-gis-boundaries-london.zip

  4. Unzip the data and save it to your current folder

5.6 Mapping in ArcMap

5.6.1 Load data

  1. Open a new ArcMap document

  1. Accept the defaults and click OK

ArcMap ‘pro’ tip. When you do any processing within ArcMap it will try and let you contiune using the software. In practice this is pretty rubbish and nearly always crashes. You can turn this off and force the software to only work on the processing by click Geoprocessing (in the top tool bar) > Geoprocessing Options then unselecting Background processing

  1. On the right hand side of the ArcMap document there should be two tabs: Catalog and Search. If they aren’t visible click Windows > Catalog, next to the little x for Catalog there will be a pin symbol that will pin it to the right hand side of the screen. Do the same for Search. Search will let you find any tool in ArcMap without knowing exactly what Toolbox it is stored in.

As we did in practical 1, let’s make a GeoDatabase to store out outputs.

  1. Under the Catalog tab, click on the connect to folder icon (small folder with plus sign), navigate to your current folder and select it

  2. Now in the Catalog tab you should see you folder that you connect it listed

  3. Make a new File GeoDatebase by right clicking on the folder connection…

  1. Name it what you like, but make sure it retains the .gdb extension

  2. Right click on it and make it the default GeoDatabase for the current map

  1. As we did in practical 1, store relative pathnames…File > Map Document Properties > Store relative pathnames to data sources

  2. Load the London boroughs shapefile using the add data button…if you are using the data from practical 1 and it’s stored in a different place you might need to make a new folder connection

  1. Load the OSM shapefiles using the add data button (pick anyone you want)…

  2. When you load the data to ArcMap you will probably be greeted with a warning…

This means that the data layer we are loading (OSM) has a different CRS to the dataframe (our current map document). If you recall from practical 1, ArcMap sets the map document CRS to that of the first layer loaded. Our London boroughs layer is in British National Grid where as are OSM layers are in WGS 1984.

  1. Close the warning

The OSM data will load and ArcMap is pretty clever here as it will project ‘on the fly’ which means it can display the data stored in one projection as if it were in another, but the actual data is not altered. This is both good and bad. Good as it let’s us visualise our data quickly, but bad because if we have data with different projections you will run into problems during processing. My advice is to load the data and pick a projection to do all processing in.

  1. Now load the gis_osm_pois_a_free_1 polygon.shp layer.

  2. In the search tool find the tool reproject

  1. Select the osm layer as the input, give your output a name (it should be within your GeoDatabase) and select the coordiate system. When you click on the coordiate system selection box you will see a drop down called layers, expand the drop down and you’ll see what cooridate reference systems are in use for each layer open within the map. If you expand British_National_Grid you’ll see the London boroughs layer…

  1. Click on British_National_Grid and select OK, under the Geographic Transformation a method will be automatically selected, click OK.

  2. The new layer will be added to the Map document so remove the old one. Right click on the old layer > Remove

5.6.2 Manipulate data

  1. You’ll notice that some of the polygons from our OSM data fall outside the London boroughs layer, let’s sort this out. We could go right ahead and clip (like a cookie cutter) our OSM based on the outline of the London boroughs but this might cut in half some of the OSM polygons…for example:

However, it’s good to think about what we are actually interested in…in this example we will explore the distribution of hotels within the London boroughs, so let’s reduce our OSM data by picking out all of the hotels.

  1. Right click on your OSM layer > Open Atrtibute Table

  2. Within the attribute table click on Select by Attributes. This lets you filter based on specifc values stored within the table…

  3. Double click on fclass and it will populate the bottom box

  4. Click unqiue values to see all of the values stored within fclass

  5. Click the = sign, then click ‘hotel’ from the unique values box…

  1. Click apply…

In the attribute table you will see 715 records are selected (as the OSM download updates your value might be slighly different to mine). You can toggle between all records and selected records.

No we need to export our select data…

  1. Close the attrbiute tabe > right click on your OSM layer > Data > Export Data. Make sure you are exporting only the selected features into your GeoDatabase (output feature class). Click on the folder icon to give your layer an appropriate name then save and OK

  1. Add the layer the map and either turn off or remove the OSM layer we dervied the hotels from..

Some of the hotels are still outside of the London boroughs, so let’s get rid of these through select by location

  1. Go: Selection (top tool bar) > Select By Location

  2. Select featues from your OSM hotel only layer, with the source layer as London boroughs. Use the spatial selection method of: are completely within the source layer. So here we are saying only select the hotels that are within the London borough vector layer. Click apply > OK

  3. Now repeat the export process and remove or turn off the original layer.

As part of this analysis it might also be useful to know how much area the hotels occupy. So lets calcualte this.

  1. Open the attribute table of your OSM hotels within London boroughs vector file. You will see a shape area field, but as we are using a local CRS now the values might be slightly different so let’s recompute it. Under Table Options select Add Field, call the new field Area2 and select the type as Float.

  1. Right click the new field > Calcualte Geometry select OK and yes to any warnings.

Now let’s calcualte how many hotels are within each London borough and their total area…

  1. Before we can use the Spatial Join tool we need to enable some extensions in ArcMap. Click Ccustomize > Extensions… and select Spatial Analyst. Save your document then close and reload it if they weren’t already selected.

  2. Using the search tool bar find the tool Spatial Join. Select the target features as the London borough vector layer and the Join Features as the OSM hotels within the London boroughs. Specify an output name (within your GeoDatabase) and leave the Join Operation as one to one.

  3. Now, in the Field Map of Join Features delete everthing except: NAME, GSS_CODE, osm_id and Area2

  4. Right click on the osm_id and select count — this will count the number of hotel shape ids within each borough, we could have used hotel name, but i noticed that some were missing. Every feature should have an ID number, so we can capture all hotels.

  1. Now do the same for Area2 but select Sum — to total the area of hotels within each borough

  2. Select the match option as contains, click show help for more information, click OK

The output has counted the number of osm_ids within each borough and summed their areas…let’s now work out the percent of each London borough covered by hotels

  1. Add a new field as we did before called percent ensuring you select Float as the type

  2. Right click the new field > Field Calculator and accept the warning message

  3. Percent will equal our (Area2/Shape_Area)*100…ArcMap computed a new area field for us

As expected the values are pretty small, but not to worry we can scale our map accordingly, but it’s also imporant to consider what is the best method to display data (e.g. counts, percentages)

ArcMap ‘pro’ tip. If you want to see almost all the analysis that has been done within a map document open the results window through: Geoprocessing (top tool bar) > Results.

Ok enough playing with the data and attributes, let’s make some maps

5.6.3 Map data

  1. There are two ‘views’ in ArcMap data view (which is what we are on) and Layout view, to switch to layout view click View (top tool bar) > Layout view

Layout view is where we make maps to export. You should see any layers you have open (ticked) within the Layout view.

  1. Layers are stored in a dataframe, to see this in action click Insert > Data Frame

You should see a new dataframe appear, if you click it you can drag in around the layout view

  1. Switch back to data view…everthing has gone? That’s because you have the new data frame activated which has no data. Right click on your original data frame (mine is called layers) and select activate

Head back to layout view and let’s make a thematic map of our data

  1. Right click on your current layer (hotels within London boroughs) select the Symbology tab then Quantities (in the left hand coloumn) use Join_Count (where we summed the hotels per borough) as the value and pick a colour ramp. Also experiment with the classify button under classificaiton. Once you are happy click OK.

You should have something like this:

How about we spice things up a bit with some more data…

Let’s have a look at Air b n b data and make a map with the same scale to compare to hotels…

  1. Download the listings.csv from here for London. Have a look at the data in excel if you wish…listings.csv.gz also has much more data.

  2. Unzip the data and add it to your current working folder

  3. In ArcMap switch back to the data view and add in your original London boroughs .shp from practical 1.

  4. Now go File > Add Data > Add XY Data

  1. Navigate your listings.csv, select longitude as the X Field and latitude as the Y Field. You now need to change the Coordiate System of the Input…click edit, scroll up and select Geographic Coordiante Systems > World > WGS 1984 then click OK and click OK abou the ID warning.

  2. When you load data through add XY you need to export it to a new layer as at the moment we are still reading off the .csv. Right click on it > Export Data, select an appropraite name, add it too the Map, then remove the .csv from ArcMap. Make sure you also reproject it to British National Grid — i forgot to do this and had to come back to this point when writing the practical!

  3. As before you need to select only those points within the London boroughs then compute the number of air b n bs per borough….have a go at this yourself, if you get stuck go back and revisit the previous instructions…To try and make the comparsion a bit more even (scientific!) we shall filter the air b n b data (using select by attrbiutes) for only rentals that are classed as Entire home/apt and are available 365 days of the year…the select by attriubte code would be: room_type = 'Entire home/apt' AND availability_365 = 365

Under layout view you should now have two maps

  1. Let’s now set the symbology range of each map to match. Here i’m going to take the hotel symbology range and apply it to the air b n b data. Open the Symbology of Air b n b layer and click Import then select the Import symbology from another layer…pick the hotel layer > OK > OK

Now rearrange the data franes in the layout view. Hint: you can click and drag, resize using the corners or right click (on the data frame itself) > Properties > Size and Position. If you check out the Frame tab you can alter that too. You can also add ruler guides by clicking in the measurement window at the top and left of the page…

To add a legend/title/North Arrow/sacle bar go Insert then select one…

If you select the defaults for the legend you can then right click it and alter all the Properties. Go to Items (tab) > Style select only Layer Name and Label

You can change the layer names by single left clicking them in the Table of Contents…

Similarly if you select the defaults for a scale bar then right click > Properties and change the division units to KM and reduce the number of dvisions and subdivisions to 2

Finally we can add an inset map…

  1. Grab a UK outline (or any other that you think is appropraite). Go to GADM and download the .shp: https://gadm.org/download_country_v3.html. Extract, unzip and put it in your current working folder.

  2. Make a new data frame in your ArcMap document in data view and add in the .shp of the UK outline — there are a few in the zipped folder so work out which one you need. You’ll need to reproject it to British National Grid like we did with our other layers and save it in your GeoDatabase

  3. As you made a new data frame and the first layer you added had the CRS of WGS84 the new data frame defaulted to this, let’s change is to British National Grid for consistency. Right click anyway on the map (white space around the polygon of the UK) > Data Frame Properties > scroll down to layers > select British National Grid. The shape of the UK should change a bit…

Cool, switch back to layer view you should see your three data frames, position them how you would like on the page…the black outline you can see is an A4 page

Hint If you right click on a layer you can zoom to it or use the + and - icons to position the layers how you like within each frame…

  1. You can also add city points and names if you want to. I get these proem the ArcGIS Hub. Dowlonad, unzip and put the shapefile in your current working folder.

  2. They are in the wrong CRS, so reproject and then extract only the points within the UK (select by location we used earlier). You should have a point file with 15 records… you could also filter them (select by attribute) on other coloumns (e.g. if you only wanted to show cities with a population greater than or equal to 250,000).

  3. Let’s show the names of the cities to give our inset map some context. Right click on the cities point layer > Properties > Labels (tab) > check Label features in this layer and select the Label Field as CITY_NAME. Change the font if you wish, click OK

  4. Let’s add some text to acknowledge where we got our data from…so websites will have a statement you can copy others you can just write a statement yourself. This dones’t always have to be on the Map but should appear on the same page. Click Insert > Text. The box will be very small, so move it and rezie. Double click to add some text….

  5. To export the map go: File > Export Map…but wait… there is an otpion to export only the ‘active’ part of the map (or the graphics extent), but to do so you’ll need to add a box or neatline around only what you want exported. Click Insert > Neatline. Once you have it in position remove the frame. Right click on the Neatline > Properties > Frame (tab) change to none.

5.6.4 Export map

  1. Go File > Export Map, save it as a .png and check the Clip Output to Graphics Extent button (at the very bottom of the box).

Here is what my Layout view looked like

And here is what my map looked like…

Note there are some issues with mine…look at the inset map and how in Scotland there are more points than place names — this is beacuse my font is too large and they overlap.

5.6.5 Model builder

The model builder is a visual interface which allows you to build up the elements of your model by dragging data, tools and iterators into the window…i’ll give a brief example with some of the data we have used

  1. Click on the ModelBuilder icon

Model builder let’s you line all the tools we have used up and then to run them automatically….here I have got my original World_Cities .shp that needs projecting and then the points within the UK extracting…

To join up the layers to the tools you can either double click on the tool and complete the fields or use the connect icon. Here i had to double click the tool to specify the new CRS. Once the model has all the required fields in changes colour, you can then validate it and run it using the tick and play button respectively.

You can also save the model (Model > Save As) to use later (basically you can make a tool like you have been using — such as reproject), but it must be saved within a toolbox.

In the next stage i’d select all my points within the UK, however select by location isn’t available in Model Builder, instead we could use Intersect or Clip. If you wanted to use selected by attribute you could use the tool Feature Class to Feature Class and specify your SQL code.

5.7 QGIS

Ok, now we’re going to reproduce our map in QIGS. As i’ve given most of the reasoning behind all the tools in the previous ArcMap section this will be more quickfire…

5.7.1 Load data

  1. Load QGIS, Open and Save a new project (Project > New)

  2. Right click on GeoPackage and create a new database to store our data in .gpkg

  3. Load our data layers: London boroughs and OSM data (OSM data should be the gis_osm_pois_a_free_1 polygon layer)

  4. Make sure the processing toolbox is active…go Plugins > Manage and Install Plugins > Installed (left side of the box that opens), Processing should be ticked….then select the cog that is in the toolbar — within the sqaure box in the image below.

You can then search for tools in the Processing Toolbox that appears on the right of QGIS.

5.7.2 Manipulate data

  1. Reproject the OSM data. If you scroll right in the dialogue box you’ll be able to save it into your GeoPackage. You might need to refresh the browers to see the layer.

  1. While we are working with projections…check the CRS of your map (bottom right)…mine is EPSG 4326 and we want it to be in British National Grid (which is ESPG: 27700), click on it, change it and apply.

  2. For completness also drag and drop your London boroughs .shp from the Layers window (bottom left) into your GeoPacakge. Remove the old one from the Layers window. Double click on the new London boroughs layer in the GeoPackage and it will open

  3. To get only the hotels out of our OSM data we can use extract by attrbitue…this is my tool dialogue box

  1. Refresh the browser —you have to do this everytime. Double click the layer to load it.

  2. Now extract by location using the file you just created and the London boroughs (so hotels within the London boroughs). Note that i selected that the hotels are within the Lonon boroughs

  1. Let’s now count our hotels per London borough using Join Attributes by Location (Summary). Note i selected the osm_id field to summarise using count in summaries to calcualte….

  1. Next up is the Air b n b data, i’ll show you how to load it then you need to produce a count of rentals per London borough using the same rules as before (entire place/apartment and available all year). To load the data click Data Source Manager > Delimited Text:

You need to:

  • Sort the projection out and save into your .gpkg

  • Select by attibute (entire place and 365 days)

  • Select by location (within London boroughs)

  • Join the output to a new (or original) London borough polygon layer

Note You can filter by multiple attributes using extract by expression…here we would use the expression ("room_type" ILIKE '%Entire home/apt%') AND ("availability_365" ILIKE '%365%') to filter based on entire home/apt and available 365 days of the year.

5.7.3 Map data

  1. So now you should have two London borough layers one with a count of all the hotels and the other with a count of all the air b n b properties…To make a thematic map right click on the hotel layer > Symbology (tab) select Graduated and your count coloumn as the coloumn, mode as natural breaks and then classify…

  1. Now save the style so we can use it on our other layer….Style > Save Style > select in Database and provide a name

  2. Go to the symbology of the other layer > select Graduated, select the correct count coloumn, then Style > Load Style, from database and your saved style should be listed.

  3. To create a new map document in QGIS go: Project > New Print Layout. The layout works by adding a new map which is a snapshop of the main QGIS document….

  4. In the main QGIS document only select your airbnb layer, right click and zoom to it. GO back to the Print Layout > Add Item > Add Map..draw a sqaure…the layer should appear…In the window at the bottom right under Item Properties select to Lock layers…so now if you were to unselect that layer it would still remain on in the Print Layout

  5. Go back to your main QGIS document, now only select the hotels layer…repeat the Add Map steps and lock the layers

  6. Make sure you give the same size to both Maps…to do so click on a Map > Item Properties (bottom right) scroll down, expand Position and Size, give the same width and height values

  1. Add some guides to line everything up go: View > Manage Guides. The guides panel will appear in the bottom right hand corner, click the + to add a guide at a distance you specify. You can then drag your maps to snap to the guides.

  2. Add a scale bar: Add Item > Add Scale Bar. To adjust it, right click > Item Properties…alter some of the properties to make it look appropraite.

  3. Add a legend: Add Item > Add Legend and draw a sqaure. Same process to adjust it. Untick Auto update then you can use the + and - icons to remove items along with the edit icon to change the text…this is what mine looks like…

  1. Add an arrow: Add Item > Add Arrow, left click to start (twice) and right click to finish.

  2. Add text: In the left hand tool bar click add text box and draw a square

  3. Let’s add our extent map, load the UK .shp, reproject it and save it into your .gpkg. Do the same for your city points but be sure to load them into your .gpkg before you run any tool (just drag and drop them). When reprojecting you might see a lot of errors for certain points in the processing box…don’t worry British National Grid only covers the UK — these errors will be for points outside of the UK which we will remove

  4. Now replicate our ArcMap inset map by opening the Layer Properties of the new cities layer > Labels > Single Labels with city name, alter any of the text styles as you wish. Also play around with the symbology..

  5. Add the new map into your map layout and move the items to appropraite locations…

This is what i came up with in my map layout

5.7.4 Export map

To export your map to a file go: Layout > Export as Image and select crop to content…and here is my map…

Note there are a few problems with my map that could be improved: (1) If you look closely at the vector layer for London you will see that one of the boroughs is missing from map (b) — this is most likely because it has no data but could easily be fixed (2) Whilst this time i’ve displayed all the city names the colour scheme needs work…for ideas on this check out colour brewer.

5.7.5 Graphical modeler

As in ArcMap we can automate the methodological process in QGIS using the graphical modeler..again i’ll provide a short example here

  1. Go: Processing > Graphical Modeler

Graphical modeler is a bit different to model builder in ArcMap, here you drag inputs and algorthims from the inputs box (bottom left) into the model, you don’t need to specify the inputs here. When you click the run buttom (play on the top toolbar) you’ll be asked to provide the layers for the inputs. The options will be limited to those you currently have open in your map…check out the model i made to automate reprojecting cities and the UK outline, then extracting the cities within the UK outline…

Make sure you save your model from the top tool bar either as a standalone model or within your project

5.8 R

Your R and geogprahical are certainly improving by now, so i’m just going to provide you with the R code i used to do this analysis…

5.8.1 Static map

## Reading layer `gis_osm_pois_a_free_1' from data source `C:\Users\Andy\OneDrive - University College London\Teaching\CASA0005repo\prac5_data\greater-london-latest-free.shp\gis_osm_pois_a_free_1.shp' using driver `ESRI Shapefile'
## Simple feature collection with 35197 features and 4 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: -0.5108706 ymin: 51.28117 xmax: 0.322123 ymax: 51.68948
## epsg (SRID):    4326
## proj4string:    +proj=longlat +datum=WGS84 +no_defs
## Reading layer `London_Borough_Excluding_MHW' from data source `C:\Users\Andy\OneDrive - University College London\Teaching\CASA0005repo\Prac1_data\statistical-gis-boundaries-london\ESRI\London_Borough_Excluding_MHW.shp' using driver `ESRI Shapefile'
## Simple feature collection with 33 features and 7 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: 503568.2 ymin: 155850.8 xmax: 561957.5 ymax: 200933.9
## epsg (SRID):    NA
## proj4string:    +proj=tmerc +lat_0=49 +lon_0=-2 +k=0.999601272 +x_0=400000 +y_0=-100000 +datum=OSGB36 +units=m +no_defs
## Reading layer `World_Cities' from data source `C:\Users\Andy\OneDrive - University College London\Teaching\CASA0005repo\prac5_data\World_Cities\World_Cities.shp' using driver `ESRI Shapefile'
## Simple feature collection with 2540 features and 13 fields
## geometry type:  POINT
## dimension:      XY
## bbox:           xmin: -176.1516 ymin: -54.792 xmax: 179.2219 ymax: 78.2
## epsg (SRID):    4326
## proj4string:    +proj=longlat +datum=WGS84 +no_defs
## Reading layer `gadm36_GBR_0' from data source `C:\Users\Andy\OneDrive - University College London\Teaching\CASA0005repo\prac5_data\gadm36_GBR_shp\gadm36_GBR_0.shp' using driver `ESRI Shapefile'
## Simple feature collection with 1 feature and 2 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: -13.69139 ymin: 49.86542 xmax: 1.764168 ymax: 61.52708
## epsg (SRID):    4326
## proj4string:    +proj=longlat +datum=WGS84 +no_defs
# plot xy data
Airbnb <- st_as_sf(Airbnb, coords = c("longitude", "latitude"), 
                   crs = 4326)

# reproject
OSM <- st_transform(OSM, 27700)
Worldcities <- st_transform(Worldcities, 27700)
UK_outline <- st_transform(UK_outline, 27700)
Airbnb <- st_transform(Airbnb, 27700)
# we don't need to reproject Londonborough, but it 
# doesn't have a CRS..you could also use set_crs
# it needs to have one for the next step
Londonborough<- st_transform(Londonborough, 27700)

#select hotels only
OSM <- OSM[OSM$fclass == 'hotel',]
Airbnb <- Airbnb[Airbnb$room_type == 'Entire home/apt' &
                   Airbnb$availability_365=='365',]

# make a function for the join
# functions are covered in practical 7
# but see if you can work out what is going on
# hint all you have to do is replace data1 and data2
# with the data you want to use

Joinfun <- function(data1, data2) {
  # join OSM and London boroughs
  joined <- st_join(data1, data2, join = st_within)
  
  # count the number of hotels per borough
  countno <- as.data.frame(plyr::count(joined$GSS_CODE))
  
  # join the count back to the borough layer
  counted <-left_join(data2, countno, by=c("GSS_CODE"="x"))
  
  return(counted)
}

# use the function for hotels
Hotels <- Joinfun(OSM, Londonborough)

# then for airbnb
Airbnb <- Joinfun(Airbnb, Londonborough)

Worldcities2 <- Worldcities[Worldcities$CNTRY_NAME=='United Kingdom'&
                              Worldcities$CITY_NAME=='Birmingham'|
                              Worldcities$CITY_NAME=='London'|
                              Worldcities$CITY_NAME=='Edinburgh',]

newbb <- c(xmin=-296000, ymin=5408, xmax=655696, ymax=1000000)
UK_outlinecrop=st_crop(UK_outline$geometry, newbb)

# now try to arrange the plots with tmap
# note that OSM is a live dataset
# so you might have more than 286 hotels in yours!
# adjust accordingly 
breaks = c(0, 5, 12, 26, 57, 286) 

#change the column name from freq for the legend
colnames(Hotels)[colnames(Hotels)=="freq"] <- "Accom count"

# plot each map
tm1 <- tm_shape(Hotels) + 
  tm_polygons("Accom count", breaks=breaks)+
  tm_legend(show=FALSE)+
  tm_layout(frame=FALSE)+
  tm_credits("(a)", position=c(0,0.85), size=1.5)

tm2 <- tm_shape(Airbnb) + 
  tm_polygons("freq", breaks=breaks) + 
  tm_legend(show=FALSE)+
  tm_layout(frame=FALSE)+
  tm_credits("(b)", position=c(0,0.85), size=1.5)

tm3 <- tm_shape(UK_outlinecrop)+ 
  tm_polygons(col="darkslategray1")+
  tm_layout(frame=FALSE)+
  tm_shape(Worldcities2) +
  tm_symbols(col = "red", scale = .5)+
  tm_text("CITY_NAME", xmod=-1, ymod=-0.5)

legend <- tm_shape(Hotels) +
    tm_polygons("Accom count") +
    tm_scale_bar(position=c(0.2,0.04), text.size=0.6)+
    tm_compass(north=0, position=c(0.65,0.6))+
    tm_layout(legend.only = TRUE, legend.position=c(0.2,0.25),asp=0.1)+
    tm_credits("(c) OpenStreetMap contrbutors and Air b n b", position=c(0.0,0.0))
  
t=tmap_arrange(tm1, tm2, tm3, legend, ncol=2)

t

We can also arrage our maps using the grid package…

5.8.2 Export

So how do we output our map then…

5.8.3 Basic interactive map

But could we not also make an interactive map like we did in practical 2?

5.8.4 Advanced interactive map

But let’s take it a bit further so we can select our layers on an interactive map..

# library for pop up boxes
library(leafpop)
library(leaflet)

#join data
ti<-st_join(Airbnb, Hotels, join = st_equals)
ti<-st_transform(ti,crs = 4326)

#remove the geometry for our pop up boxes to avoid
#the geometry field 
ti2 <- ti
st_geometry(ti2) <- NULL
popairbnb <- popupTable(ti2, zcol=c("NAME.x", "GSS_CODE.x", "freq"))
pophotels <- popupTable(ti2, zcol=c("NAME.x", "GSS_CODE.x", "Accom count"))

# set the colour palettes using our previously defined breaks
# the colour palettes are the same using the same breaks
# but different data
pal <- colorBin(palette = "YlOrRd", domain=ti2$freq, bins=breaks)
pal2 <- colorBin(palette = "YlOrRd", domain=ti2$`Accom count`, bins=breaks)

map<- leaflet(ti) %>%
  
  # add basemap options
  addTiles(group = "OSM (default)") %>%
  addProviderTiles(providers$Stamen.Toner, group = "Toner") %>%
  addProviderTiles(providers$Stamen.TonerLite, group = "Toner Lite") %>%
  addProviderTiles(providers$CartoDB.Positron, group = "CartoDB")%>%
  
  #add our polygons, linking to the tables we just made
  addPolygons(color="white", 
              weight = 2,
              opacity = 1,
              dashArray = "3",
              popup = popairbnb,
              fillOpacity = 0.7,
              fillColor = ~pal(freq),
              group = "Airbnb")%>%
  
  addPolygons(fillColor = ~pal(`Accom count`), 
              weight = 2,
              opacity = 1,
              color = "white",
              dashArray = "3",
              popup = pophotels,
              fillOpacity = 0.7,group = "Hotels")%>%
  # add a legend
  addLegend(pal = pal2, values = ~`Accom count`, group = c("Airbnb","Hotel"), 
            position ="bottomleft") %>%
  # specify layers control
  addLayersControl(
    baseGroups = c("OSM (default)", "Toner", "Toner Lite", "CartoDB"),
    overlayGroups = c("Airbnb", "Hotels"),
    options = layersControlOptions(collapsed = FALSE)
  )

# plot the map
map

If you want to explore Leaflet more have a look at this website

To see other basemap options (there are loads!) have a look here: http://leaflet-extras.github.io/leaflet-providers/preview/

5.9 Bad maps

What makes a bad map then… and what should you avoid:

  • Poor labeling — don’t present something as an output with the file name (e.g. layer_1_osm) in the legend — name your layers properly, it’s really easy to do and makes a big difference to the quality of the map.
  • No legend
  • Screenshot of the map — export it properly, we’ve been doing this a while and can tell
  • Change the values in the legend … what is aesthetically more pleasing 31.99999 or 32?. Make it as easy as possible to interpret your map.
  • Too much data presented on one map — be selective or plot multiple maps
  • Presented data is too small or too big — be critical about what you produce, it should be easy to read and understand
  • A map or figure without enough detail — A reader should be able to understand a map or figure using the graphic in the figure/map and the caption alone! A long caption is fine assuming it’s all relevant information.

For more cartography ideas/advice have a look at this blog post, consult axis map catography guide and check out the data is beautiful reddit.

Another decent resource is the Fundamentals of Data Visualization book

5.10 Feedback

Was anything that we explained unclear this week or was something really clear…let us know using the feedback form. It’s anonymous and we’ll use the responses to clear any issues up in the future / adapt the material.