I try to create a map of the Middle East and North Africa region including country names. The map is defined by latitude and longitude coordinates. Several non-MENA countries are included in the resulting map, and I want to label with country names only the countries belonging to the region by defining them using the 'filter' function with a vector of country names. After having inserted the filter function, I get the error message: "Error in data.matrix(data) : 'list' object cannot be coerced to type 'double'". The map writes out fine when I don't include the filter with the vector of country names.
The following code runs fine:
ggplot(data = world) +
geom_sf(fill= "antiquewhite") +
geom_text(data = world_points , aes(x=X, y=Y, label=name),
color = "darkblue", fontface = "bold", check_overlap = TRUE) +
annotate(geom = "text", x = 20, y = 35, label = "MØNA",
fontface = "italic", color = "grey22", size = 6) +
coord_sf(xlim = c(-18.0, 72.0), ylim = c(11.5, 45.0), expand = FALSE) +
xlab("lengdegrader") + ylab("breddegrader") +
ggtitle("Midtøsten og Nord-Afrika") +
theme(panel.background = element_rect(fill = "aliceblue"))
But this produces the error. Something must be wrong in the geom_text function, but I cannot figure out what:
ggplot(data = world) +
geom_sf(fill = "antiquewhite") +
coord_sf(xlim = c(-18.0, 72.0), ylim = c(11.5, 45.0), expand = FALSE) +
geom_text(data = world_points %>%
filter(name %in% c('Egypt', 'Tunisia', 'Algeria', 'Libya',
'Morocco', 'Sudan', 'Jordan', 'Israel',
'Palestine', 'Syria', 'Iraq', 'Turkey',
'Iran', 'Afghanistan', 'Saudi Arabia', 'Kuwait',
'United Arab Emirates', 'Qatar', 'Oman', 'Yemen', 'Bahrain',
'Lebanon')), aes(x=X, y=Y, label=name),
color = "darkblue", size = 3, check_overlap = FALSE) +
annotate(geom = "text", x = 20, y = 35, label = "MØNA",
fontface = "italic", color = "grey22", size = 6) +
xlab("lengdegrader") + ylab("breddegrader") +
ggtitle("Midtøsten og Nord-Afrika") +
theme(panel.background = element_rect(fill = "aliceblue"))
When putting text on maps plotted using ggplot2::geom_sf()
you will be better served by ggplot2::geom_sf_text()
(the sf part is important!) than plain ggplot2::geom_text()
.
This function will take the text position from the {sf}
object that serves as data
- thus removing the need to specify the x and y coordinates (the information is present in data
already). Label argument works as expected
To sum it up:
geom_text
call to geom_sf_text
aes()
callYou will want to tune the label placement and what not, but it is a start...
library(dplyr)
library(ggplot2)
library(sf)
world <- giscoR::gisco_get_countries() %>%
mutate(name = NAME_ENGL)
world_points <- st_centroid(world)
ggplot(data = world) +
geom_sf(fill = "antiquewhite") +
coord_sf(xlim = c(-18.0, 72.0), ylim = c(11.5, 45.0), expand = FALSE) +
geom_sf_text(data = world_points %>%
filter(name %in% c('Egypt', 'Tunisia', 'Algeria', 'Libya',
'Morocco', 'Sudan', 'Jordan', 'Israel',
'Palestine', 'Syria', 'Iraq', 'Turkey',
'Iran', 'Afghanistan', 'Saudi Arabia', 'Kuwait',
'United Arab Emirates', 'Qatar', 'Oman', 'Yemen', 'Bahrain',
'Lebanon')), aes(label=name),
color = "darkblue", size = 3, check_overlap = FALSE) +
annotate(geom = "text", x = 20, y = 35, label = "MØNA",
fontface = "italic", color = "grey22", size = 6) +
xlab("lengdegrader") + ylab("breddegrader") +
ggtitle("Midtøsten og Nord-Afrika") +
theme(panel.background = element_rect(fill = "aliceblue"))