Line segments leaving the interior of a map of brazil using package ggrepel

Asked

Viewed 113 times

4

I am trying to reproduce the format of the map below, however, I have been facing some problems to insert these "straights" on the map. After a search, I found the package ggrepel that brings with it a series of functions capable of accomplishing the desired. For more details see: https://ggrepel.slowkow.com/articles/examples.html.

I intend to insert a red dot in each state of the map with the "straight" coming out of it, and then add some numerical information, basically it would be next to the following example:

However, I have been facing the error that is being presented in the code below.

The data is available here: https://drive.google.com/file/d/1TuApNsGtVfNVcGOHmEB-5qVxObRa13V7/view?usp=sharing

library(geobr)
library(ggplot2)
library(ggrepel)

states <- read_state(code_state = "all",year = 2019)
states <- dplyr::left_join(states, dados, by = c("name_state" = "uf"))

ggplot(states) +
  geom_sf(data = states, aes(fill = AreaTotal)) +
  geom_sf_label(aes(label = states$abbrev_state),label.padding = unit(0.8, "mm"),size = 4)+
  geom_point(data = states, color = "red")

Erro: geom_point requires the following missing aesthetics: x and y
Run `rlang::last_error()` to see where the error occurred.
Além disso: Warning messages:
1: Use of `states$abbrev_state` is discouraged. Use `abbrev_state` instead. 
2: In st_point_on_surface.sfc(sf::st_zm(x)) :
  st_point_on_surface may not give correct results for longitude/latitude data


````
  • 1

    In this example, you’re not even using the package ggrepel . For arrows you must choose between geom_label_repel() or geom_text_repel(). Note that the two functions want the points/coordinates where the arrows/lines should be inserted. I suggest you consult this material here. The error shown in the function geom_point(), values of x and y missing...

  • Thank you Rodrigo Silva!!

1 answer

6


I do not use geobr, I used a shapefile that I already have, simplified IBGE shapefiles. As geobr accesses IBGE FTP, the result will be the same.

library(sf)
library(ggrepel)

states <- st_read("~/Shapefiles/IBGE/ufs.shp")

> head(as.data.frame(states), 3)
#>          NM_ESTADO SIGLA_UF CD_GEOCUF    NM_REGIAO                       geometry
#> 1 Distrito Federal       DF        53 Centro-Oeste POLYGON ((-47.57461 -15.513...
#> 2             Pará       PA        15        Norte POLYGON ((-49.19353 -7.0407...
#> 3             Acre       AC        12        Norte POLYGON ((-67.13424 -9.6762...

The error you are getting is because you are not indicating to geom_point the x and y coordinates of the points. Sf objects have the coordinates grouped in the field "geometry", need to indicate it in aesthetics. Also need to indicate to stat the function sf_coordinates, which converts to xy coordinates (in the case of a polygon, will calculate the centroid). The same should be done for geom_text_repel.

ggplot(states, aes(geometry = geometry)) +
  geom_sf() +
  geom_point(stat = "sf_coordinates", color = "red") +
  geom_text_repel(aes(label = SIGLA_UF),
    stat = "sf_coordinates",
    segment.curvature = 1e-20, # para "entortar" a reta
    force = 1e4) +
  theme_void()

inserir a descrição da imagem aqui

I used force just as an example. To place labels at the positions you want around the map, you need to set the offset values for each point with nudge_x and nudge_y or provide for data manual coordinates. See help from geom_text_repel for details.

Points independent of the geometry of the sf

If you have geographical coordinates of the points independent of the geometry of the polygons, you can use these data as the basis of the map and include the sf below. Here is an example of crowding the capitals, using the geographical coordinates of Brazilian municipalities maintained in Github by Kelvin S. do Prado.

centro.mun <- read.csv("https://raw.githubusercontent.com/kelvins/Municipios-Brasileiros/main/csv/municipios.csv")

capitais <- merge(as.data.frame(states)[2:3],
                  subset(centro.mun, capital == 1, select = c(2:4,6)),
              by.x = "CD_GEOCUF", by.y = "codigo_uf")

ggplot(capitais, aes(longitude, latitude)) +
  geom_sf(data = states, inherit.aes = FALSE) +
  geom_text_repel(aes(label = nome), force = 1e3) +
  geom_point(color = "red") +
  scale_x_continuous(expand = expansion(mult = c(.2, .4))) + # aumenta espaço lateral
  theme_void()

inserir a descrição da imagem aqui

  • 1

    It was really good. I wonder if the red dots could be placed in the capital of each state, but I believe this would add an extra level of complexity to the problem.

  • Thank you Carlos Eduardo.

  • 1

    @Yes, the points can be placed in the capitals (or anywhere else), but since the position in this case is not a function of the polygons, the coordinates need to be informed independently. I will update the response to include this case.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.