geobr
e
tmap
- dados de competitividade municipal CLPAbstract
In this exercise I use R and tmap and geobr packages to map the Competitiveness indexes for municipalities in Brazil. It’s written in portuguese and, so, I encourage non-portuguese speakers to open the html post in Google Chrome or similar with the translate option.This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
As ideias aqui expressas são de responsabilidade exclusiva do autor, e não representam as opiniões da instituição a que pertence.
Sugestão para citação: FIGUEIREDO, Adriano Marcos Rodrigues. Mapas em
R com geobr
e tmap
- dados de competitividade
municipal CLP`. Campo Grande-MS,Brasil: RStudio/Rpubs, 2025. DisponÃvel
em https://rpubs.com/amrofi/mapas-com-geobr-tmap/.
Para realizar seu mapa em R, inicialmente o leitor deve baixar os programas e pacotes necessários ao projeto. Neste caso, sugere-se que utilize o RStudio e o R atualizados, a partir de: http://cran.r-project.org/bin/windows/base/ e https://www.rstudio.com/products/rstudio/download3/. Quando esta revisão foi feita, a versão do RStudio era a RStudio 2025.05.0 Build 496 e do R version 4.5.1 for Windows (32/64 bit).
Primeiro instale o R e posteriormente o RStudio, de modo que o segundo reconheça automaticamente o primeiro. Se tudo estiver perfeito, a tela inicial do RStudio mostrará corretamente a versão do R.
Agora a meta é gerar um mapa simples em R. Para tanto, primeiro
define-se a malha municipal desejada. Para o presente caso, utilizam-se
as malhas digitais do pacote geobr
.
Os pacotes (previamente instalados) são aqui carregados:
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.2 ✔ tibble 3.2.1
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.0.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(geobr)
## Carregando namespace exigido: sf
library(ggplot2) # Para manipulação de dados espaciais
library(sf) # Para manipulação de dados espaciais
## Linking to GEOS 3.13.1, GDAL 3.10.2, PROJ 9.5.1; sf_use_s2() is TRUE
library("ggspatial") # Para visualização espacial
library(rgeoda)
## Carregando pacotes exigidos: digest
library(tmap)
O pacote geobr
tem as rotinas para o download dos mapas
com divisões territoriais variadas. Faremos para os municÃpios
brasileiros, malha com a estrutura municipal de 2024, contendo 5.571
municÃpios. É importante o leitor ter essa estrutura em mente, pois ao
longo dos anos, municÃpios são criados a partir de desmembramentos de
outros, não necessariamente respeitando limites de distritos ou outros
atributos previamente definidos.
library(geobr)
options(timeout= 4000000)
mapa_br <- read_municipality(code_muni = "all", year = 2024)
saveRDS(mapa_br,"mapa_br.rds")
mapa_br <- readRDS("F:/disciplinas/economia regional/laboratorio_R/competitividade_CLP/mapa_br.rds")
names(mapa_br) # Verificar nomes das colunas do mapa
## [1] "code_muni" "name_muni" "code_state" "abbrev_state" "name_state"
## [6] "code_region" "name_region" "geom"
class(mapa_br) # [1] "sf" "data.frame"
## [1] "sf" "data.frame"
# [1] "code_muni" "name_muni" "code_state" "abbrev_state" "name_state" "code_region" "name_region" "geom"
É possÃvel verificar que esse objeto é da classe sf
e
data.frame
. Um objeto sf
contém uma coleção de
recursos incluindo atributos e geometrias que contemplam os aspectos
espaciais para desenhar o mapa.
Primeiro vou trabalhar com os dados para plotar com ggplot2. Vou carregar os dados de competitividade do CLP, disponÃveis em: https://rankingdecompetitividade.org.br/municipios/.
# Dados de municipios_ranking-geral.csv
municipios<- read_csv("municipios_ranking-geral.csv", skip = 1)
## Rows: 418 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): Nome
## dbl (4): Código IBGE, Posição, Variação, Nota Normalizada
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# juntar mapa_br com municipios, preservando formato sf
mapa_ranking <- left_join(mapa_br, municipios, by=c("code_muni"="Código IBGE"))
class(mapa_ranking) # [1] "sf" "data.frame"
## [1] "sf" "data.frame"
# Verificar se houve perda de linhas
nrow(mapa_br) # 5571 ok
## [1] 5571
nrow(municipios) # 418
## [1] 418
nrow(mapa_ranking) # 5571 ok
## [1] 5571
# Verificar nomes das colunas
names(mapa_ranking)
## [1] "code_muni" "name_muni" "code_state" "abbrev_state"
## [5] "name_state" "code_region" "name_region" "Nome"
## [9] "Posição" "Variação" "Nota Normalizada" "geom"
# [1] "code_muni" "name_muni" "code_state" "abbrev_state" "name_state" "code_region"
# [7] "name_region" "Nome" "Posição" "Variação" "Nota Normalizada" "geom"
# Mapa colorido com classes de ranking ----
min(mapa_ranking$`Nota Normalizada`, na.rm=TRUE) # [1] 30.4
## [1] 30.4
max(mapa_ranking$`Nota Normalizada`, na.rm=TRUE) # [1] 62.47
## [1] 62.47
# fazer classes de cores para o mapa, de 30 até 65 de 5 em 5, para variável mapa_ranking$`Nota Normalizada`
mapa_ranking <- mapa_ranking %>%
mutate(classe_ranking = case_when(
`Nota Normalizada` < 35 ~ "[30-35(",
`Nota Normalizada` >= 35 & `Nota Normalizada` < 40 ~ "[35-40(",
`Nota Normalizada` >= 40 & `Nota Normalizada` < 45 ~ "[40-44(",
`Nota Normalizada` >= 45 & `Nota Normalizada` < 50 ~ "[45-49(",
`Nota Normalizada` >= 50 & `Nota Normalizada` < 55 ~ "[50-54(",
`Nota Normalizada` >= 55 & `Nota Normalizada` < 60 ~ "[55-59(",
`Nota Normalizada` >= 60 ~ "[60-65(",
TRUE ~ NA_character_
))
# Mapa do Brasil com classes de ranking ----
ggplot() +
geom_sf(data=mapa_ranking,
aes(fill=`classe_ranking`),
color= "black", size=.15)+
labs(title="Competitividade dos MunicipÃos Brasileiros - CLP",
caption='Fonte: Elaboração própria com dados básicos da CLP', size=8)+
scale_fill_discrete(name="Classes de Ranking")+
theme_minimal()+
annotation_north_arrow(location = "bl", # norte magnetico no mapa
which_north = "true",
pad_x = unit(0.65, "in"),
pad_y = unit(0.3, "in"),
style = north_arrow_fancy_orienteering) +
annotation_scale(location = "bl", width_hint = 0.3) # barra de escala no mapa
## Scale on map varies by more than 10%, scale bar may be inaccurate
Agora vou criar um shapefile que pode ser utilizado em outros programas como o Geoda, QGIS, ArcGIS, PhilCarto etc.
# Gerar shapefile do mapa_ranking ----
# antes de criar shapefile vou mudar code_muni para character
mapa_ranking.shp <- mapa_ranking %>%
mutate(code_muni = as.character(code_muni))
st_write(mapa_ranking.shp, "mapa_ranking.shp", delete_dsn = TRUE)
## Warning in abbreviate(fld_names, minlength = 7): abbreaviate usado com
## caracteres não-ASCII
## Warning in abbreviate_shapefile_names(obj): Field names abbreviated for ESRI
## Shapefile driver
## Deleting source `mapa_ranking.shp' using driver `ESRI Shapefile'
## Writing layer `mapa_ranking' to data source
## `mapa_ranking.shp' using driver `ESRI Shapefile'
## Writing 5571 features with 12 fields and geometry type Multi Polygon.
#
# Usar rgeoda para fazer o mapa de quebras naturais (natural breaks) ----
# com a variável NtNrmlz do shapefile mapa_ranking.shp
# o pacote já está instalado e carregado
# carregar shapefile
mapa_ranking.shp2 <- st_read("mapa_ranking.shp")
## Reading layer `mapa_ranking' from data source
## `F:\disciplinas\economia regional\laboratorio_R\competitividade_CLP\mapa_ranking.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 5571 features and 12 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -73.98681 ymin: -33.75108 xmax: -28.84778 ymax: 5.26962
## Geodetic CRS: SIRGAS 2000
# Usar rgeoda para fazer o mapa de quebras naturais (natural breaks) ----
# com a variável NtNrmlz do shapefile mapa_ranking.shp
# o pacote já está instalado e carregado
# mapa_ranking.shp2 carregado
names(mapa_ranking.shp2)
## [1] "code_mn" "name_mn" "cod_stt" "abbrv_s" "nam_stt" "cod_rgn"
## [7] "nam_rgn" "Nome" "Posição" "Variaçã" "NtNrmlz" "clss_rn"
## [13] "geometry"
# [1] "code_mn" "name_mn" "cod_stt" "abbrv_s" "nam_stt" "cod_rgn" "nam_rgn"
# [8] "Nome" "Posição" "Variaçã" "NtNrmlz" "clss_rn" "geometry"
# [1] 30.40 36.24 41.08 45.92 50.76 55.60 60.44 62.47
# https://geodacenter.github.io/opioid-environment-toolkit/visualizeArealData-tutorial.html
Agora fazendo o mapa pelo tmap a partir do shapefile.
tmap_mode('plot') # modo plot
## ℹ tmap mode set to "plot".
p1 <- tm_shape(mapa_ranking.shp2) +
tm_fill(
fill = "NtNrmlz",
fill.scale = tm_scale_intervals(
breaks = c(-Inf, 30.400, 36.720, 43.930, 47.450, 49.760, 53.680, Inf),
values = c("#FFFFCC","#FADC86","#F9C652","#E48629",
"#CC5C0D","#A44507","#732000"),
value.na = "#FFFFCC" # cor para os NAs
),
fill.legend = tm_legend(
title = "Ranking Normalizado: Quebras Naturais"
)
) +
tm_borders() +
tm_title("Ranking CLP - Jenks - Quebras Naturais", size = 0.9) +
tm_layout(
frame = FALSE,
legend.outside = TRUE,
legend.outside.position = "right",
legend.title.size = 0.9
) +
# 👉 Norte geográfico (estrela)
tm_compass(type = "8star", position = c("right", "bottom"), size = 2) +
# 👉 Barra de escala (v4 usa tm_scalebar)
tm_scalebar(position = c("left", "bottom"))
p1
## Scale bar set for latitude km and will be different at the top and bottom of the map.
tmap_save(p1, 'CLP_Rank_Norm_Jenks.png')# save the map in a .png file
## Scale bar set for latitude km and will be different at the top and bottom of the map.
## Map saved to F:\disciplinas\economia regional\laboratorio_R\competitividade_CLP\CLP_Rank_Norm_Jenks.png
## Resolution: 2223.67 by 1983.208 pixels
## Size: 7.412235 by 6.610692 inches (300 dpi)
Vou chamar o mapa salvo como ‘CLP_Rank_Norm_Jenks.png’.