ggmap legend not showing - r

I have two dataframes both recording the top 10 stations riders went. One is for casual rider, the other one is for member rider. Both dataframes contain column 'station','freq','latitude','longitude'. I'm able to use ggmap to plot the graph showing the locations of the stations from both dataframes, but not able to show the legend.
R scripe is showing below:
library(ggplot2)
library(rstudioapi)
library(ggmap)
map_location <- c (lon = -87.623177, lat = 41.881832)
chicago_map_zoom <- get_map (location = map_location,
maptype = 'roadmap',
color='bw',
source='google',
zoom=13,
)
chicago_plot <- ggmap(chicago_map_zoom) +
geom_point (data = casual_top_station,
aes (x = longitude,
y = latitude),
color = "red",
shape = 15,
alpha = 0.5,
size = 3) +
geom_point (data = member_top_station,
aes (x = longitude,
y = latitude),
color = "blue",
shape = 16,
alpha = 0.5,
size = 2) +
scale_color_identity (name = "Subscription type",
breaks = c("red","blue"),
labels = c("Casual","Member"),
guide = "legend") +
theme (axis.ticks = element_blank(),
axis.text = element_blank(),
axis.title = element_blank()) +
labs (title = "Top 10 casual and member rider stations",
subtitle = "Both start and end stations")
Result graph: Chicago_map

Instead of using scale_color_identity ... to set the values for color, shape and size I would suggest to first an id column to your data.frames
which could then be mapped on aesthetics inside aes. Afterwards set your desired colors, shapes and sizes via the scale_xxx_manual family of functions.
Using some fake data for the points:
library(ggplot2)
library(ggmap)
casual_top_station <- data.frame(
longitude = -87.65,
latitude = 41.9
)
member_top_station <- data.frame(
longitude = -87.65,
latitude = 41.86
)
casual_top_station$id <- "Casual"
member_top_station$id <- "Member"
legend_title <- "Subscription type"
base <- ggmap(chicago_map_zoom) +
scale_color_manual(values = c(Casual = "red", Member = "blue")) +
scale_shape_manual(values = c(Casual = 15, Member = 16)) +
scale_size_manual(values = c(Casual = 3, Member = 2)) +
theme(
axis.ticks = element_blank(),
axis.text = element_blank(),
axis.title = element_blank()
) +
labs(
title = "Top 10 casual and member rider stations",
subtitle = "Both start and end stations",
color = legend_title, shape = legend_title, size = legend_title
)
base +
geom_point(
data = casual_top_station,
aes(
x = longitude,
y = latitude,
color = id, shape = id, size = id
),
alpha = 0.5
) +
geom_point(
data = member_top_station,
aes(
x = longitude,
y = latitude,
color = id, shape = id, size = id
),
alpha = 0.5
)
Also, to simplify your code further I would suggest to bind both data frames by row using e.g. dplyr::bind_rows which would allow to add your points via just one geom_point.
top_station <- dplyr::bind_rows(casual_top_station, member_top_station)
base +
geom_point(
data = top_station,
aes(
x = longitude,
y = latitude,
color = id, shape = id, size = id
), alpha = .5)

Related

Why do I get a blank animation instead of a map and two geom_points on top?

I tried to produce a gganimation with two geoms on a map of germany, but eventually only produced a blank animation.
This here is a reproducible example of the animation I tried to produce:
# Load necessary packages
pacman::p_load(ggplot2, tidyverse, maps, mapdata,
gganimate, av, emojifont)
# Production of example data
{
set.seed(123)
index = rep(c(1:10),
each = 100) ; year = rep(c(1951:1960),
each = 10, times = 10); month = rep(c(1:10),
each = 1,
times = 100)
variable_of_interest = runif(1000,
min = 0,
max = 0.4); season = rep(x = c("Winter", "Winter", "Spring", "Spring", "Spring",
"Summer", "Summer", "Summer", "Autmn", "Autmn"),
times = 100)
lat = rep(c(seq(from = 48,
to = 53,
length = 10)),
each = 100); lon = rep(c(seq(from = 7,
to = 14,
length = 10)),
each = 100)
Variable_of_Interest = as.data.frame(cbind(index, year, month, variable_of_interest, season, lat, lon))
Variable_of_Interest$month_of_year = paste0(Variable_of_Interest$year,
"-",
Variable_of_Interest$month)
#Variable_of_Interest = Variable_of_Interest[order(Variable_of_Interest$year,
# Variable_of_Interest$month),]
rownames(Variable_of_Interest) = NULL
}
# Transform columns from character to numeric
Variable_of_Interest = mutate_at(Variable_of_Interest,
c(1,2,3,4,6,7),
as.numeric)
# Preperation for the animation
season_symbols = c("Spring" = emoji("cherry_blossom"),
"Summer" = emoji("tropical_drink"),
"Autmn" = emoji("fallen_leaf"),
"Winter" = emoji("snowflake"))
# Map of values of the variable of interest
Variable_of_Interest_Map = ggplot(Variable_of_Interest) +
geom_path(data = map_data("world","Germany"),
aes(x = long,
y = lat,
group = group)) +
coord_fixed(xlim = c(6,
15),
ylim = c(47,
55)) +
geom_point(aes(x=lon,
y=lat,
group = month_of_year,
shape = season),
size = 10) +
scale_shape_manual(values = season_symbols, breaks = c("Spring", "Summer", "Autmn", "Winter")) +
geom_point(aes(x=lon,
y=lat,
group = month_of_year),
colour = ifelse(test = Variable_of_Interest$variable_of_interest > 0.3,
I("red"),
I("blue"))) +
# scale_color_gradient(low="blue", high="yellow") +
xlab("Longitude (degree)") +
ylab("Latitude (degree)") +
theme_bw() +
transition_manual(frames = month_of_year) +
theme(legend.position = "bottom",
legend.title = element_text(size=12, face="bold"),
panel.background = element_blank(),
legend.background = element_blank()) +
labs(title = '{unique(Variable_of_Interest$month_of_year)[as.integer(frame)]}',
color = paste0("Variable of Interest"),
shape = "season")
anim_save("Variable-of-Interest.mp4",
animate(
Variable_of_Interest_Map,
nframes = 1000,
renderer = ffmpeg_renderer()
))
The plan was to draw a map of germany, use one set of geom_points to represent the variation of the variable_of_interest among the locations in Germany through time and another set of geom_points to visualize the present season through drawing symbols like snowflakes for winter.
The main issue with your code is that you tried to display your emojis via the shape aes and a geom_point which at least on my machine resulted in an error. Also I have not found any reference on using emoji font like that. Instead you could achieve your desired result using a geom_text to which end I added a column to your data containing the season symbol and which could be mapped on the label aes:
library(tidyverse)
library(emojifont)
library(gganimate)
Variable_of_Interest$season_symbol <- season_symbols[Variable_of_Interest$season]
Variable_of_Interest_Map <- ggplot(Variable_of_Interest) +
geom_path(
data = map_data("world", "Germany"),
aes(
x = long,
y = lat,
group = group
)
) +
coord_fixed(
xlim = c(
6,
15
),
ylim = c(
47,
55
)
) +
geom_text(
aes(
x = lon,
y = lat,
group = month_of_year,
label = season_symbol
),
size = 10, family = "EmojiOne"
) +
geom_point(aes(
x = lon,
y = lat,
colour = ifelse(variable_of_interest > 0.3, "red", "blue"),
group = month_of_year
)) +
scale_color_manual(values = c(red = "red", blue = "blue"), guide = "none") +
xlab("Longitude (degree)") +
ylab("Latitude (degree)") +
theme_bw() +
transition_manual(frames = month_of_year) +
theme(
legend.position = "bottom",
legend.title = element_text(size = 12, face = "bold"),
panel.background = element_blank(),
legend.background = element_blank()
) +
labs(
title = "{unique(Variable_of_Interest$month_of_year)[as.integer(frame)]}",
color = paste0("Variable of Interest"),
shape = "season"
)
Variable_of_Interest_Map

ggplot: change color of bars and not show all labels in legend

I have not been working with r for long, but have already found many answers to my questions in this community. But now I can't get any further and ask my first own question.
Objective: I want to display values from different years (here in the example 10 years) over time in a barplot. Each year should be represented by a column. The years 1 to 9 should get a uniform color, the 10th year another. For the 10th year the value should also be displayed. There should be only two entries in the legend: "Year 1 - 9" and "Year 10".
I have created the following dummy data set:
library(ggplot2)
# texts 2 display
tit <- "Title"
subtit <- "Subtitle"
lab <- c("lab1", "lab2", "lab3", "lab4")
# prepare dataset with random data
n_label <- length(lab)
cohort <-
c(
rep("year01", n_label),
rep("year02", n_label),
rep("year03", n_label),
rep("year04", n_label),
rep("year05", n_label),
rep("year06", n_label),
rep("year07", n_label),
rep("year08", n_label),
rep("year09", n_label),
rep("year10", n_label)
)
data_rel <- runif(40, min = 0, max = .5)
df_data <- data.frame(lab, cohort, data_rel)
df_data %>% summarise(count = n_distinct(cohort)) -> n_cohort
I was able to implement the plot as desired with the following code:
# plot data
df_data %>%
ggplot() +
geom_bar (aes(
x = factor(lab, levels = c("lab1", "lab2", "lab3", "lab4")),
y = data_rel,
fill = cohort
),
stat = "identity",
position = position_dodge()) +
scale_y_continuous(labels = scales::percent, limits = c(0, 1)) +
theme_classic() +
theme(
legend.position = "bottom",
plot.title = element_text(hjust = 0.5,
size = 14,
face = "bold"),
plot.subtitle = element_text(hjust = 0.5),
plot.caption = element_text(hjust = 0.5),
) +
geom_text(
data = subset(df_data, cohort == "year10"),
aes(
x = lab,
y = data_rel,
label = paste0(sprintf("%.1f", data_rel * 100), "%")
),
vjust = -1,
hjust = -1.5,
size = 3
) +
scale_fill_manual(
values = c("#7F7F7F", "#389DC3"),
limits = c("year01", "year10"),
labels = c("Year 1 - 9", "Year 10")
) +
labs(
subtitle = paste(subtit),
title = str_wrap(tit, 45),
x = "",
y = "",
fill = ""
)
Unfortunately, I cannot adjust the colors of the columns for years 1 - 9. Either not all columns get the correct color, or I get unwanted entries in the legend.
Does anyone have an idea what i am doing wrong? I am grateful for every hint!
In setting the fill attribute you can group all other levels of the factor together (here using forcats::fct_other to collapse Years 1-9 into one level) to give your two levels of fill colours. At the same time, using group = cohort will keep bars separate:
library(forcats)
# plot data
df_data %>%
ggplot() +
geom_bar (aes(
x = factor(lab, levels = c("lab1", "lab2", "lab3", "lab4")),
y = data_rel,
group = cohort,
fill = fct_other(cohort, "year10", other_level = "year01")
),
stat = "identity",
position = position_dodge()) +
scale_y_continuous(labels = scales::percent, limits = c(0, 1)) +
theme_classic() +
theme(
legend.position = "bottom",
plot.title = element_text(hjust = 0.5,
size = 14,
face = "bold"),
plot.subtitle = element_text(hjust = 0.5),
plot.caption = element_text(hjust = 0.5),
) +
geom_text(
data = subset(df_data, cohort == "year10"),
aes(
x = lab,
y = data_rel,
label = paste0(sprintf("%.1f", data_rel * 100), "%")
),
vjust = -1,
hjust = -1.5,
size = 3
) +
scale_fill_manual(
values = c("#7822CC", "#389DC3"),
limits = c("year01", "year10"),
labels = c("Year 1 - 9", "Year 10")
) +
labs(
subtitle = paste(subtit),
title = str_wrap(tit, 45),
x = "",
y = "",
fill = ""
)
(Changed manual fill colour to distinguish from unfilled bars)
It's also possible to do by creating a new 2-level cohort_lumped variable before passing to ggplot(), but this way helps keep your data as consistent as possible up to the point of passing into graphing stages (and doesn't need extra columns storing essentially same information).

How to draw an arc on top of a plot map overlay made with ggmap in R

I created a multi-layer map using ggmap() in R. I would like to add an arc between two points on the map. I tried doing so with geom_curve(). This doesn't work. The two maps in the overlay are then no longer properly superimposed. I suspect this is due to the different projections within the map overlay, but I don't fully understand this.
Is there a way to specify a coordinate reference system (CRS) for an arc that matches the CRS in use in the map already? Or a totally different way I could add one arc between two points in my exisiting map?
A similar question with an accepted solution was already asked on stack overflow ("Draw curved lines in ggmap, geom_curve not working"). However, as noted there, the solution doesn't work for larger map areas.
Here is a minimal working example with some comments:
My system
I'm using R 4.2.0 with RStudio version 2022.02.3 Build 492.
Required Packages
install.packages("rnaturalearth")
install.packages("devtools") # Needed for rnaturalearthhires
devtools::install_github("ropensci/rnaturalearthhires") # Ditto
install.packages("ggmap")
install.packages("ggplot2")
install.packages("dplyr")
install.packages("PBSmapping") #For clipping polygons
install.packages("ggsn") #For the scale bar
library(rnaturalearth)
library(rnaturalearthhires) # Needed for scale = large in ne_countries()
library(ggmap)
library(ggplot2)
library(dplyr)
library(PBSmapping)
library(ggsn)
Plot a map that includes Germany and Saudi Arabia
Define the map for the region including Germany and Saudi Arabia (KSA) with
latitude and longitude (x min, y min, x max, y max)
GermanyKSA_map_coordinates <- c(5, 16, 56, 56)
Set unique values for the two countries for coloring them on the larger map
GermanyKSA_values <- data.frame(region = factor(c("Germany", "Saudi Arabia")), data = c(15, 15))
Get an existing map of the region including both countries
GermanyKSA_map <- get_map(location = GermanyKSA_map_coordinates, source = "stamen", zoom = 6)
Get country polygon data and join these to the unique values
world <- ne_countries(scale = "large", returnclass = "sf")
mapdata <- map_data("world")
GermanyKSA_mapdata <- left_join(mapdata, GermanyKSA_values, by = "region")`
Create a bounding box for the region map
GermanyKSA_map_bb <- attr(GermanyKSA_map, "bb")
GermanyKSA_ylim <- c(GermanyKSA_map_bb$ll.lat, GermanyKSA_map_bb$ur.lat)
GermanyKSA_xlim <- c(GermanyKSA_map_bb$ll.lon, GermanyKSA_map_bb$ur.lon)`
Clip polygons to match the map
colnames(GermanyKSA_mapdata)[1:6] <- c("X","Y","PID","POS","region","subregion")
GermanyKSA_mapdata <- clipPolys(GermanyKSA_mapdata, xlim = GermanyKSA_xlim, ylim = GermanyKSA_ylim, keepExtra = TRUE)`
Add dots for the cities Regensburg, Germany, and Al-Hofuf, Saudi Arabia
Regensburg_Dot <- c(12.1015461, 49.0204469)
AlHofuf_Dot <- c(49.401569, 25.363091)`
Create a data frame with the dot coordinates
Dots <- rbind(Regensburg_Dot, AlHofuf_Dot) %>% as.data.frame()
Rename the columns
colnames(Dots) <- c("long", "lat")
Plot map overlay. Provides exactly what I need, only an arc between the two cities is missing
ggmap(GermanyKSA_map) +
coord_map(xlim = GermanyKSA_xlim, ylim = GermanyKSA_ylim) +
geom_polygon(data = GermanyKSA_mapdata, aes(x = X, y = Y, group = PID, fill = data),
color = "black", alpha=0.5) +
geom_point(data = Dots, aes(x = long, y = lat), col = "#990022", size = 4) +
scalebar(x.min = 5, x.max = 56, y.min = 16, y.max = 56, dist = 500,
dist_unit = "km", transform = TRUE, anchor = c(x = 52, y = 54),
box.fill = c("#990022", 'grey'), box.color = c("#990022", 'grey'),
st.dist = .025, st.size = 3) +
theme(legend.position = "none") +
theme(axis.title.x = element_blank(), axis.title.y = element_blank()) +
ggtitle("Regensburg–Al-Hofuf: 4,093 km")`
Unsuccessful attempt to add an arc between both points (Regensburg and Al-Hofuf)
Create data frame for drawing an arc
RegensburgToAlHofuf <- data.frame(Regensburg_x = 12.1015461,
Alhofuf_x = 49.401569, Regensburg_y = 49.0204469, Alhofuf_y = 25.363091)`
Plot map overlay, now with an attempt to draw an arc with geom_curve(). Resulting warning: "geom_curve is not implemented for non-linear coordinates"
ggmap(GermanyKSA_map) +
coord_map(xlim = GermanyKSA_xlim, ylim = GermanyKSA_ylim) +
geom_polygon(data = GermanyKSA_mapdata, aes(x = X, y = Y, group = PID,
fill = data), color = "black", alpha=0.5) +
geom_point(data = Dots, aes(x = long, y = lat), col = "#990022", size = 4) +
geom_curve(data = RegensburgToAlHofuf,
aes(x = Regensburg_x, y = Regensburg_y, xend = Alhofuf_x, yend = Alhofuf_y),
size = 1.5, color = "#990022", curvature = 0.15, inherit.aes = TRUE) +
scalebar(x.min = 5, x.max = 56, y.min = 16, y.max = 56, dist = 500,
dist_unit = "km", transform = TRUE, anchor = c(x = 52, y = 54),
box.fill = c("#990022", 'grey'), box.color = c("#990022", 'grey'),
st.dist = .025, st.size = 3) +
theme(legend.position = "none") +
theme(axis.title.x = element_blank(), axis.title.y = element_blank()) +
ggtitle("Regensburg–Al-Hofuf: 4,093 km")`
I added a call to a map projection, coord_cartesian(), following suggestion in "Draw curved lines in ggmap, geom_curve not working". However, plots are not correctly superimposed. I also tried coord_quickmap() instead of coord_cartesian(), which also didn't work.
ggmap(GermanyKSA_map) +
coord_map(xlim = GermanyKSA_xlim, ylim = GermanyKSA_ylim) +
geom_polygon(data = GermanyKSA_mapdata, aes(x = X, y = Y, group = PID,
fill = data), color = "black", alpha=0.5) +
geom_point(data = Dots, aes(x = long, y = lat), col = "#990022", size = 4) +
geom_curve(data = RegensburgToAlHofuf,
aes(x = Regensburg_x, y = Regensburg_y, xend = Alhofuf_x, yend = Alhofuf_y),
size = 1.5, color = "#990022", curvature = 0.15, inherit.aes = TRUE) +
scalebar(x.min = 5, x.max = 56, y.min = 16, y.max = 56, dist = 500,
dist_unit = "km", transform = TRUE, anchor = c(x = 52, y = 54),
box.fill = c("#990022", 'grey'), box.color = c("#990022", 'grey'),
st.dist = .025, st.size = 3) +
theme(legend.position = "none") +
theme(axis.title.x = element_blank(), axis.title.y = element_blank()) +
ggtitle("Regensburg–Al-Hofuf: 4,093 km") +
coord_cartesian()`

How to supress/combine the legend for two geoms in R

Im making a scatterplot which shows a value plotted against the date since symptom onset. These patients are categorised based on disease severity, and i wanted to show how the values change over time in each severity category. I have coloured the dots based on severity score, but i prefer to use shape =21 so i can have a border. I also draw a line to see the trend, and i want that coloured in the same way, however, this has added another legend and it looks complicated. This issue doesnt happen if use a different shape that isnt filled, because scale_colour_manual can be used for both the lines and the dots, but i dont think it looks as nice. Any idea how i can fix this?
IC50SymObySS <- ggplot(data = isaric) +
geom_point(mapping = aes(x = Days_since_onset, y = log2IC50, fill = Severity_score), size = 2, colour = "black", shape = 21)+
geom_smooth(mapping = aes(x = Days_since_onset, y = log2IC50, colour = Severity_score), se = FALSE)+
scale_fill_manual(breaks=c("1","2","3","4","5"),
values=c("1" = "lightblue1","2" = "lightblue3","3" = "lightblue4","4" = "lightcoral","5" = "firebrick2"),
labels=c("1","2","3","4","5"),
name = "Severity Score")+
scale_colour_manual(values=c("1" = "lightblue1","2" = "lightblue3","3" = "lightblue4","4" = "lightcoral","5" = "firebrick2"))+
theme_minimal()+
JTheme+
ylab("Serum Log2 IC50")+
xlab("Days Since Symptom Onset")+
guides(colour = guide_legend(title.position = "top", title.hjust = 0.5))
IC50SymObySS
As per this answer, you need to use identical name and labels values for both fill and colour scale.
library(ggplot2)
library(dplyr)
isaric <- transmute(iris,
Days_since_onset = (Sepal.Length - 4)^3,
log2IC50 = Sepal.Width * 3,
Severity_score = cut(Petal.Length, breaks = quantile(Petal.Length, prob = 0:5 / 5), labels = 1:5))
ggplot(data = isaric) +
geom_smooth(mapping = aes(x = Days_since_onset, y = log2IC50, colour = Severity_score), se = FALSE)+
geom_point(mapping = aes(x = Days_since_onset, y = log2IC50, fill = Severity_score), size = 2, colour = "black", shape = 21)+
scale_colour_manual(
name = "Severity Score",
values=c("1" = "lightblue1","2" = "lightblue3","3" = "lightblue4","4" = "lightcoral","5" = "firebrick2"),
labels=c("1","2","3","4","5"))+
scale_fill_manual(
name = "Severity Score",
breaks=c("1","2","3","4","5"),
values=c("1" = "lightblue1","2" = "lightblue3","3" = "lightblue4","4" = "lightcoral","5" = "firebrick2"),
labels=c("1","2","3","4","5"))+
theme_minimal()+
ylab("Serum Log2 IC50")+
xlab("Days Since Symptom Onset")+
guides(colour = guide_legend(title.position = "top", title.hjust = 0.5))

Create ggmap with points, faceted, and each facet zoomed appropriately?

I want to plot data points for various cities over a greyed-out map from google. As these cities are some distance from each other, I thought I would use a faceted plot.
Creating the map is easy enough; see image and code below. However, each facet shows the same area - in this case Greater London - with the result that the points for other cities are not shown.
Ideally I would like each facet to show each city with the relevant points overlaid. So the facet 'Cardiff' would show a zoomed map of Cardiff and its data points, 'Birmingham' would show Birmingham and its points and so on. I've tried changing various parameters such as zoom and center but I haven't been successful.
How can I show a different city and the relevant points in each facet?
require(ggmap)
require(reshape)
# create fake data
sites <- data.frame(site = 1:6,
name = c(
"Royal Albert Hall",
"Tower of London",
"Wales Millenium Centre",
"Cardiff Bay Barrage",
"Birmingham Bullring",
"Birmingham New Street Station"
),
coords = c(
"51.501076,-0.177265",
"51.508075,-0.07605",
"51.465211,-3.163208",
"51.44609,-3.166652",
"52.477644,-1.894158",
"52.477487,-1.898836"),
subzone = rep(c('London','Cardiff','Birmingham'), each = 2)
)
# use function from reshape to split/add column
sites = transform(sites,
new = colsplit(coords, split = ",", names = c('lat', 'lon')))
names(sites) <- c(names(sites)[1:4], 'lat','lon')
ggmap(get_googlemap(center = "London", # omitting this doesn't help
scale = 2,
zoom = 11, # fiddling with zoom doesn't work
color = 'bw',
maptype = 'roadmap',
extent = 'panel',
format = "png8",
filename = "facet_map_test",
)) +
facet_wrap(~ subzone, ncol = 1) +
geom_point(data = sites,
aes(x = lon, y = lat),
fill = "red",
size = 3,
colour = "black",
shape = 21,
alpha = 1) +
theme(legend.position = "none") +
theme()
Using the gridExtra package is probably the best way to go. The code:
# getting the maps
londonmap <- get_map(location = c(lon = -0.1266575, lat = 51.504575), zoom = 12)
cardiffmap <- get_map(location = c(lon = -3.16493, lat = 51.45565), zoom = 13)
birminghammap <- get_map(location = c(lon = -1.896497, lat = 52.477565), zoom = 14)
# plotting the maps
p1 <- ggmap(londonmap) +
geom_point(data = sites[sites$subzone == "London",],
aes(x = lon, y = lat, fill = "red", alpha = 0.8, size = 3),
shape = 21) +
ggtitle("London") +
theme(axis.title = element_blank(), legend.position = "none", plot.margin = unit(c(0,0,0,0), "lines"))
p2 <- ggmap(cardiffmap) +
geom_point(data = sites[sites$subzone == "Cardiff",],
aes(x = lon, y = lat, fill = "red", alpha = 0.8, size = 3),
shape = 21) +
ggtitle("Cardiff") +
theme(axis.title = element_blank(), legend.position = "none", plot.margin = unit(c(0,0,0,0), "lines"))
p3 <- ggmap(birminghammap) +
geom_point(data = sites[sites$subzone == "Birmingham",],
aes(x = lon, y = lat, fill = "red", alpha = 0.8, size = 3),
shape = 21) +
ggtitle("Birmingham") +
theme(axis.title = element_blank(), legend.position = "none", plot.margin = unit(c(0,0,0,0), "lines"))
# grouping the plots together in one plot
grid.arrange(p1, p2, p3, ncol = 1)
The result:

Resources