GET00183 - Visualização de Dados
Nos dias atuais, é muito comum nos depararmos com dados georreferenciados. O crescimento de dados espaciais é relativamente recente. Porém, já experimentamos seus efeitos no dia a dia.
Visualizações de dados espaciais é fundamental para quem trabalha com análise de dados.
1 - Shapefile
Se o intuito é representar o espaço de interesse, precisamos inicialmente discutir sobre o shapefile.
Um shapefile é um formato popular de arquivo contendo dados geoespaciais em forma de vetor usado por Sistemas de Informações Geográficas (SIG). Shapefiles espaciais descrevem geometrias: pontos, linhas e polÃgonos. Entre outras coisas, essas geometrias podem representar Poços, Rios, cidades, respectivamente.
O formato shapefile define a geometria e os atributos dos recursos referenciados geograficamente em três ou mais arquivos com extensões de arquivo especÃficas que devem ser armazenadas no mesmo espaço de trabalho do projeto. Eles são:
- .shp - O arquivo principal que armazena a geometria do recurso, obrigatório,
- .shx - O arquivo de Ãndice que armazena o Ãndice da geometria do recurso, obrigatório,
- .dbf - A tabela do dBASE que armazena as informações de atributos dos recursos, obrigatório,
- .prj, .sbn, .sbx, .fbn, .fbx, .ain, .aih, .atx, .ixs, .mxs, .xml, .cpg são outras extensões possÃveis.
Alguns arquivos podem ser obtidos no site do IBGE (https://www.ibge.gov.br/geociencias/downloads-geociencias.html).
Acessem o site e sigam o seguinte caminho: Organização do territorio \(>\) malhas territoriais. Vocês terão acesso:
- malhas de setores censitários,
- malhas municipais,
- malhas do Brasil por municÃpio.
Atividade: Baixem o arquivo do Estado do Rio de Janeiro do ano de 2016 contendo os municÃpios. Vejam quantos arquivos foram baixados e quais suas extensões.
1.1 - Importando Shapefile
Para importamos um shapefile para o R usaremos a função st_read do pacote sf.
A seguir, vamos apresentar os principais argumentos da função st_read:
 - dsn - o nome do arquivo a ser importado (com extensão .shp).
Atividade: Importe o arquivo Bairros_Recife.shp e armazene-o em um objeto chamado recife. Para que a importação ocorra, é preciso que todos os arquivos auxiliares do shapefile estejam na mesma pasta.
# Carregando o pacote
library(sf)
# Importando o shapefile
recife = st_read(dsn = "Bairros_Recife.shp")Reading layer `Bairros_Recife' from data source
`/Users/jonyarrais/Documents/Universidade Federal Fluminense/Disciplinas/GET00183 Visualizacao de Dados/Topico 07 - Mapas/Bairros_Recife.shp'
using driver `ESRI Shapefile'
Simple feature collection with 94 features and 10 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 277547.5 ymin: 9098032 xmax: 295287.7 ymax: 9123296
Projected CRS: SIRGAS 2000 / UTM zone 25S
# Verificando a classe do objeto recife
class(x = recife)[1] "sf" "data.frame"
# Visualizando o objeto
recifeSimple feature collection with 94 features and 10 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 277547.5 ymin: 9098032 xmax: 295287.7 ymax: 9123296
Projected CRS: SIRGAS 2000 / UTM zone 25S
First 10 features:
CBAIRRCODI VBAIRROID EBAIRRNOME CRPAAACODI CMICROCODI TBAIRRULAT
1 19 0 RECIFE 1 1 1899-12-30
2 27 0 SANTO ANTONIO 1 2 1899-12-30
3 35 0 SAO JOSE 1 2 1899-12-30
4 43 0 ILHA JOANA BEZERRA 1 3 1899-12-30
5 51 0 CABANGA 1 2 1899-12-30
6 60 0 COELHOS 1 3 1899-12-30
CEMPRECODI AUSUACMATR EBAIRRNO_1 EBAIRRLINK
1 0 0 Recife <NA>
2 0 0 Santo Antônio <NA>
3 0 0 São José <NA>
4 0 0 Ilha Joana Bezerra <NA>
5 0 0 Cabanga <NA>
6 0 0 Coelhos <NA>
geometry
1 MULTIPOLYGON (((294617.4 91...
2 MULTIPOLYGON (((293353.3 91...
3 MULTIPOLYGON (((292458 9107...
4 MULTIPOLYGON (((290464.9 91...
5 MULTIPOLYGON (((291566 9106...
6 MULTIPOLYGON (((291634.3 91...
[ reached 'max' / getOption("max.print") -- omitted 4 rows ]
# Carregando o pacote
library(tidyverse)
## Para plotar somente o contorno do objeto recife
ggplot(recife) +
geom_sf(fill = "White")# Selecionando o shape do bairro de Boa Viagem
Boa_viagem = recife |>
filter(EBAIRRNOME=="BOA VIAGEM")
# Visualizando o objeto Boa_viagem
Boa_viagemSimple feature collection with 1 feature and 10 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 288679.6 ymin: 9098032 xmax: 292546.5 ymax: 9104302
Projected CRS: SIRGAS 2000 / UTM zone 25S
CBAIRRCODI VBAIRROID EBAIRRNOME CRPAAACODI CMICROCODI TBAIRRULAT CEMPRECODI
1 205 0 BOA VIAGEM 6 1 1899-12-30 0
AUSUACMATR EBAIRRNO_1 EBAIRRLINK geometry
1 0 Boa Viagem <NA> MULTIPOLYGON (((289794.1 90...
# Plotando o shape de Boa Viagem
ggplot(Boa_viagem) +
geom_sf() +
theme_light()# Unindo poligonos no shapefile
novo_recife = recife |>
group_by(CRPAAACODI) |>
summarize(n = n())
# Visualizando o novo objeto
novo_recifeSimple feature collection with 6 features and 2 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 277547.5 ymin: 9098032 xmax: 295287.7 ymax: 9123296
Projected CRS: SIRGAS 2000 / UTM zone 25S
# A tibble: 6 x 3
CRPAAACODI n geometry
<dbl> <int> <POLYGON [m]>
1 1 11 ((291961.1 9106271, 291904.5 9106181, 291809.5 9106087, 2918…
2 2 18 ((292947.8 9110818, 292828.9 9110761, 292304.3 9110516, 2922…
3 3 29 ((291025.2 9109306, 291015 9109290, 291011.5 9109285, 290968…
4 4 12 ((290538.5 9108381, 290538.7 9108375, 290539.1 9108365, 2905…
5 5 16 ((287570 9103879, 287570.4 9103875, 287570.4 9103875, 287565…
6 6 8 ((292546.5 9104121, 292546.5 9104121, 292509.4 9104020, 2924…
# Plotando o novo objeto
ggplot(data = novo_recife) +
geom_sf(fill = "White") +
theme_light()Determinados shapifiles podem ser porduzidos com uma quantidade muito grande de pontos para definir os contornos da região de interesse. Nestes casos, os mapas que serão plotados serão pesados e provavelmente demoram a carregar. Existe uma forma de deixar esses arquivos mais leves nestes cenários.
# Carregando o pacote
library(rmapshaper)
# Simplificando o shape
Recife_simples = ms_simplify(input = recife,
keep = 0.1,
keep_shapes = TRUE)O argumento input é o shape a ser simplificado, o keep é a proporção dos pontos que você deseja manter e o keep_shapes = TRUE impede que caracterÃsticas pequenas dos polÃgonos sumam, no caso de uma grande simplificação.
# Plotando o objeto simplificado
ggplot(data = Recife_simples) +
geom_sf(fill = "White") +
theme_light()2 - Mapa de pontos
Quando possuÃmos as coordenadas (lat/long) da ocorrência de um evento de interesse, uma visualização apropriada é a criação de um mapa de pontos. Neste mapa é possÃvel avaliar a existência de aglomerações dos pontos em algumas localidades da região de interesse.
Atividade: Importem o arquivo nyshape.shp e armazenem em um objeto chamado NYShp.
# Visualizando o objeto
NYShpSimple feature collection with 71 features and 3 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -74.25559 ymin: 40.49612 xmax: -73.70001 ymax: 40.91553
Geodetic CRS: WGS84(DD)
# A tibble: 71 x 4
shape_leng boro_cd shape_area geometry
<dbl> <dbl> <dbl> <MULTIPOLYGON [°]>
1 51550. 311 103177785. (((-73.97299 40.60881, -73.97259 40.60667, -73…
2 65822. 313 88195686. (((-73.98372 40.59582, -73.98305 40.59541, -73…
3 52246. 312 99525500. (((-73.9714 40.64826, -73.97121 40.64762, -73.…
4 37008. 304 56663217. (((-73.89647 40.68234, -73.89653 40.682, -73.8…
5 62240. 209 114266297. (((-73.83979 40.83562, -73.83967 40.8356, -73.…
6 83998. 212 154896607. (((-73.79386 40.88364, -73.79417 40.88299, -73…
7 35876. 206 42664311. (((-73.87185 40.84376, -73.87192 40.84345, -73…
8 47817. 208 92071724. (((-73.89663 40.91142, -73.89663 40.9113, -73.…
9 32820. 226 50566411. (((-73.8679 40.90294, -73.86796 40.90281, -73.…
10 43327. 317 93810207. (((-73.90755 40.65119, -73.90849 40.65059, -73…
# … with 61 more rows
Atividade: Importem o arquivo NYPD.csv e armazenem em um objeto chamado NYPD.
O arquivo contém dados sobre crimes ocorridos na cidade de Nova York. Entre as variáveis disponibilizadas, podemos citar o tipo do crime (TYPE), as coordenadas (latitude e longitude), entre outras.
# Visualizando o objeto
NYPD# A tibble: 407 x 6
LAW_CAT_CD TYPE BORO_NM Day Longitude Latitude
<chr> <chr> <chr> <dbl> <dbl> <dbl>
1 FELONY VANDALISM QUEENS 1 -73.7 40.7
2 FELONY ROBBERY BRONX 1 -73.9 40.9
3 FELONY ROBBERY QUEENS 3 -73.8 40.7
4 FELONY ROBBERY BROOKLYN 4 -74.0 40.7
5 FELONY ROBBERY QUEENS 2 -73.8 40.7
6 FELONY VANDALISM QUEENS 5 -73.8 40.7
7 FELONY ROBBERY STATEN ISLAND 6 -74.2 40.6
8 FELONY ROBBERY QUEENS 3 -73.7 40.7
9 FELONY ROBBERY BRONX 2 -73.9 40.9
10 FELONY MURDER QUEENS 3 -73.8 40.7
# … with 397 more rows
Vamos fazer o mapa de pontos dos crimes na cidade de Nova York usando o ggplot2.
#Plotando as localizações dos delitos
ggplot(data = NYShp) +
geom_sf(fill = "White") +
geom_point(data = NYPD,
aes(x = Longitude,
y = Latitude),
colour = 'Dark Blue') +
theme_light()Vale ressaltar que o data indicado na função ggplot é o shape, já no geom_point foi preciso especificar um data diferente, a base de dados.
O pacote ggmap fornece uma função que nos permite criar um mapa de pontos diferente.
#Uma outra possibilidade
library(ggmap)
qmplot(x = Longitude,
y = Latitude,
data = NYPD,
colour = I('red'),
size = I(1.5),
darken = 0.3)No mapa acima, o size controla o tamanho, o darken a opacidade e o colour a cor do ponto. Percebam, que não precisamos do shape para construir o mapa.
Tanto com o ggplot como no ggmap é possÃvel criar mapas de pontos indicando os diferentes tipos de crime, por exemplo.
# Mapa de pontos indicando o tipo de crime com o ggplot2
mapa1 = ggplot(data = NYShp) +
geom_sf(fill = "White") +
geom_point(data = NYPD,
aes(x = Longitude,
y = Latitude,
colour = TYPE),
size = 0.8) +
theme_light()
# Mapa de pontos indicando o tipo de crime com o ggmap
mapa2 = qmplot(x = Longitude,
y = Latitude,
data = NYPD,
colour = TYPE,
size = I(1),
darken = 0.3)
# Carregando pacote
library(gridExtra)
#Plotando os dois maps
grid.arrange(mapa1,mapa2, ncol=2)Atividade: Com base no conteúdo da disciplina visto até o momento, crie o código necessário para reproduzir a visualização abaixo.
3 - Mapa coroplético
Mapas coropléticos são usados em cenários no qual a variável de interesse foi observada de forma agregada para alguma partição em áreas do espaço de interesse. Por exemplo, suponha que foram observados o número de roubos de carros nos bairros da cidade do Rio de Janeiro. Neste cenário, a região de interesse é o Rio de Janeiro, que está particionada em seus bairros e a variável foi observada de forma agregada paea cada área.
Atividade: Importe o arquivo Vendas_agregada_bairro.csv e guarde em um objeto chamado base_venda.
A base fornece o registro do número de produtos vendidos (por semestre e no ano todo) por bairro de um determinado produto, entre outras.
#Visualinado a base de dados
base_venda# A tibble: 94 x 6
no_bairro_residencia num.vendas.1sem num.vendas.2sem num.vendas gasto
<chr> <dbl> <dbl> <dbl> <dbl>
1 PAU FERRO 1 0 1 4460
2 SANTO ANTONIO 6 2 8 4590
3 PAISSANDU 11 4 15 4369
4 ILHA DO LEITE 18 1 19 4614
5 SOLEDADE 1 20 21 4788
6 JAQUEIRA 20 4 24 4652
7 TORREAO 3 27 30 4794
8 CABANGA 6 25 31 4647
9 SANTANA 12 21 33 4852
10 DERBY 20 14 34 4832
# … with 84 more rows, and 1 more variable: porc_panfletagem <dbl>
Para criarmos um mapa coropléticos precisamos inicialmente acrescentar a variável de interesse ao shape. Faremos isso, fazendo um merge da base com o shape. Neste caso, usamos o left_join passando como base inicial o shape, para garantir que a base que será retornada terá exatamente as linhas que já existem no shape e usamos os nomes dos bairros para fazer a junção.
#Fazendo a relacao dos dois data frames
recife = left_join(x = recife,
y = base_venda,
by = c("EBAIRRNOME" = "no_bairro_residencia"))
# Visualizando o objeto
recifeSimple feature collection with 94 features and 15 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 277547.5 ymin: 9098032 xmax: 295287.7 ymax: 9123296
Projected CRS: SIRGAS 2000 / UTM zone 25S
First 10 features:
CBAIRRCODI VBAIRROID EBAIRRNOME CRPAAACODI CMICROCODI TBAIRRULAT
1 19 0 RECIFE 1 1 1899-12-30
2 27 0 SANTO ANTONIO 1 2 1899-12-30
3 35 0 SAO JOSE 1 2 1899-12-30
4 43 0 ILHA JOANA BEZERRA 1 3 1899-12-30
CEMPRECODI AUSUACMATR EBAIRRNO_1 EBAIRRLINK num.vendas.1sem
1 0 0 Recife <NA> 39
2 0 0 Santo Antônio <NA> 6
3 0 0 São José <NA> 163
4 0 0 Ilha Joana Bezerra <NA> 187
num.vendas.2sem num.vendas gasto porc_panfletagem
1 42 81 4811 0.7075714
2 2 8 4590 0.1632857
3 58 221 4980 0.7220000
4 271 458 5082 0.7294286
geometry
1 MULTIPOLYGON (((294617.4 91...
2 MULTIPOLYGON (((293353.3 91...
3 MULTIPOLYGON (((292458 9107...
4 MULTIPOLYGON (((290464.9 91...
[ reached 'max' / getOption("max.print") -- omitted 6 rows ]
A seguir, apresentamos o mapa coroplético do número de produtos vendidos no ano.
#Mapa coropletico do numero de vendas de produto
ggplot(data = recife) +
geom_sf(aes(fill = num.vendas))Como alterar caracterÃsticas deste gráfico?
#Modificando o mapa coropletico
ggplot(data = recife) +
geom_sf(aes(fill = num.vendas)) +
scale_fill_gradient(name = "Vendas",
low = "White",
high = "Red") +
theme_light() +
theme(legend.title = element_text(size = 16,
colour = "Red",
face = "bold"),
legend.text = element_text(size = 10,
colour = "Red"))O pacote tmap é outro pacote bastante útil para a criação de mapas coropléticos.
#Carregando pacote tmap
library(tmap)
#Construindo o mapa coropletico para vendas
tm_shape(shp = recife) +
tm_fill(col = "num.vendas",
palette = "Greens",
title = "Vendas")## tm_shape - cria um elemento tmap que especifica um objeto espacial
## tm_fill - cria um elemento tmap que desenha e preenche o mapa
#Argumentos:
#shp - um objeto da classe sf
#col - a variavel/atributo que deseja plotar
#palette - a paleta de cores
#title - Nome que deseja mostrar no titulo da legenda
#Transformando em uma geometria valida
recife = st_make_valid(x = recife)
## st_make_valid - transforma uma geometria invalida em uma valida
#Argumentos:
#x - um objeto da classe sf
#Modificando o numero de intervalos
tm_shape(shp = recife) +
tm_fill(col = "num.vendas",
n = 4,
palette = "Greens",
title = "Vendas")#Definindo os limites e o numero de intervalos
mapa = tm_shape(shp = recife) +
tm_fill(col = "num.vendas",
breaks = quantile(recife$num.vendas, probs = seq(0,1,.1)),
palette = "Greens",
title = "Vendas") +
tm_borders(lwd = 0.75,
lty = "solid")
## tm_borders - desenha as bordas que separam os poligonos
#Argumentos:
#lwd - espessura da borda
#lty - tipo de linha
#Visualizando o mapa
mapa#Mudando o estilo do mapa com tm_style (pre-definido)
mapa +
tm_style("cobalt")#Mudando o estilo do mapa com tm_layout (criar)
mapa +
tm_layout(title = "2018",
legend.outside = TRUE,
legend.text.color = "Dark Green")## tm_layout - especifica configuracoes para o layout do mapa
#Argumentos:
#title - um titulo acima da legenda
#legend.outside - para a legenda aparecer ao lado de fora do mapa
#legend.text.color - cor da legenda
#Incluindo texto nos mapas
mapa +
tm_text(text = "EBAIRRNOME",
size = "num.vendas",
legend.size.show = FALSE) +
tm_layout(legend.outside = TRUE)## tm_text - especifica nomes para os poligonos
#Argumentos:
#text - variavel que deseja aparecer como texto nos poligonos
#size - numero ou uma variavel que vai determinar o tamanho da fonte
#legend.size.show - se deseja apresentar a legenda para os diferentes tamanhos da letra
#Grafico para mais de uma variavel
tm_shape(shp = recife) +
tm_fill(col = c("num.vendas.1sem","num.vendas.2sem"),
title = c("1 Sem", "2 Sem"),
palette = "Reds") +
tm_facets(nrow = 1) +
tm_borders() +
tm_layout(legend.position = c("left","bottom"))#Colocando todos os graficos em uma mesma escala
tm_shape(shp = recife) +
tm_fill(col = c("num.vendas.1sem","num.vendas.2sem"),
title = "Vendas",
palette = "Reds") +
tm_facets(nrow = 1,
free.scales = FALSE) +
tm_borders() +
tm_layout(panel.labels = c("1 Sem","2 Sem"))