if(!require(pacman)) install.packages("pacman")
Loading required package: pacman
p_load(raster, terra, sf)
The purpose of this document is to instruct you on how to add kernel density estimates to your plot axes. In this case, axes will be applied to modeled geographic data.
First you’ll need to ensure that you’ve loaded the appropriate packages for the task. As I will be manipulating light pollution data, my ‘geographic’ packages are as follows:
if(!require(pacman)) install.packages("pacman")
Loading required package: pacman
p_load(raster, terra, sf)
For brevity, I have used the p_load(...)
function from the pacman
package to load:
raster
terra
sf
Axes, are best added using the ggplot2
and its extensions, ggspatial
and ggExtra
.
p_load(ggplot2, ggspatial, ggExtra)
First, I will load my data. Here, I have saved an old workspace that contains a shapefile loaded as ‘Bristol_data’. This file contains a field that relates to light pollution values in Bristol.
You can simply replace this step with a process you prefer to use to load your shapefile data.
load(url("https://github.com/Richtea84/StudentHelp/raw/refs/heads/main/Bristol_data.RData"))
I want to create a choropleth that features distributions for “High” and “Low” light pollution values in my data.
$Hi_Low <- ifelse(Bristol_data$LP < median(Bristol_data$LP), "Low", "High") Bristol_data
We can preview the result using ggplot2
(Figure 1).
ggplot(data = Bristol_data)+
geom_sf(aes(color = Hi_Low))+
::annotation_north_arrow()+
ggspatialtheme_minimal()
The first step in the process is to save the initial ggplot as an object. Here, it is called map_obj
:
ggplot(data = Bristol_data)+
geom_point(aes(x = lon, y = lat, color = Hi_Low))+
theme_minimal() -> map_obj
We now use the ggMarginal(...)
function to on the object and specify basic colour and fill aesthetics (Figure 2).
ggMarginal(map_obj, groupColour = T, groupFill = T)
To project your data as a map, you need to invoke the geom_sf(...)
function in your ggplot object. In this example, we will attempt to show polygon geometries instead of the points - the data we’ll be using is called geog_data.
To prepare this data, first we ensure the geometries are set to longitude and latitude (WGS: 4326). A data join can then be accomplished (object called geog_data_2
:
# Syncing the projection:
<- st_transform(geog_data, 4326)
geog_data
# Joining the polygonal data to the points geometries
<- merge(x = geog_data, as.data.frame(st_drop_geometry(Bristol_data)), by = "lso11cd") geog_data_2
The merge(...)
function doesn’t work for two sf objects. Therefore, you need to convert points data into a data frame that excludes geometries.
Finally, we can produce the map (Figure 3).
ggplot(data = Bristol_data)+
geom_sf(data = geog_data)+
geom_point(aes(x = lon, y = lat, color = Hi_Low), alpha = 0,show.legend = FALSE)+
labs(fill = "Light Pollution")+
theme_minimal()+
theme(legend.position = "bottom") -> map_obj
+
map_objgeom_sf(data = geog_data_2, aes(fill = Hi_Low), alpha = 0.7)+
::annotation_north_arrow()-> map_obj2
ggspatial
ggMarginal(map_obj2, groupColour = T, groupFill = T)