Search code examples
rggplot2r-sfgeom-textaesthetics

ggplot2 and eurostat: row removed due to missing values (geom_text) using geom_sf_text


Using Eurostat I try to plot some values to the map of the EU, using the following code:

library(tidyverse)
library(eurostat)
library(leaflet)
library(sf)
library(scales)
library(cowplot)
library(ggthemes)

#----------- load dataset -----------
SHP <- get_eurostat_geospatial(resolution = 10, 
                        nuts_level = 0,
                        year = 2021)

#select EU countries only
EU28 <- eu_countries %>% 
  select(geo = code, name)
EU29 <- rbind(EU28, c("NO", "Norge"))  # add Norway since not EU country

SHP_29 <- SHP %>% 
  select(geo = NUTS_ID, geometry) %>% 
  inner_join(EU29, by = "geo") %>% 
  arrange(geo) %>% 
  st_as_sf()


# ------------ create values to map on EU --------------
test = data.table(
  geo=EU29$geo,
  values=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29)
)
test <- SHP_29 %>% inner_join(test, by="geo") %>% arrange(geo) %>%  st_as_sf()
test$values <- as.numeric(test$values)
testSum= sum(test$values)


#---------- plot ---------- #
test %>% 
  ggplot(aes(fill=test$values)) +
  geom_sf() +
  geom_sf_text(aes(label=test$values)) +
  scale_fill_distiller(
    palette = 1,
    direction = 1,   # reverse default order
    name = "ID"
  ) +
  scale_x_continuous(limits = c(-10, 35)) +
  scale_y_continuous(limits = c(35, 70)) +
  labs(
    title = "Test",
    subtitle = sprintf("Countries=%s", testSum),
  ) +
  theme_void()

This results in a beautiful map. However, the value for Norway (=29) is not plotted on the map. Which is probably due to the second warning message obtained when plotting:

Warning messages:
1: In st_point_on_surface.sfc(sf::st_zm(x)) : st_point_on_surface may not give correct results for longitude/latitude data
2: Removed 1 rows containing missing values (geom_text).

Why does ggplot2 or eurostat skip plotting the value for Norway?


Solution

  • Besides the solution of @m-viking (which I did not try) it is also possible to alter the specific nudge of Norway (or any other country of interest) like this:

    test2 <- test %>%
      mutate(my_nudge_x=ifelse(geo=='NO',-15,0) ,
             my_nudge_y=ifelse(geo=='NO',-20,0) ,
             geo = ifelse(geo=='NO','Nudged NO', geo)
    
    test %>% 
      ggplot(aes(fill=test$values)) +
      geom_sf() +
      geom_sf_text(aes(label=test$values),
      nudge_x = test2%my_nudge_x,
      nudge_y = test2%my_nudge_y,
      ) +
      scale_fill_distiller(
        palette = 1,
        direction = 1,   # reverse default order
        name = "ID"
      ) +
      scale_x_continuous(limits = c(-10, 35)) +
      scale_y_continuous(limits = c(35, 70)) +
      labs(
        title = "Test",
        subtitle = sprintf("Countries=%s", testSum),
      ) +
      theme_void()
    
    

    the coordinates for my_nudge_x and my_nudge_y were found using trial&error.

    Thanks to https://community.rstudio.com/t/geom-sf-text-change-position-of-only-one-text-label/73419/4