Dados Georreferenciados: Exploração e Visualização com Python

Joao Anselmo
Creditas Tech
Published in
8 min readJan 31, 2022

Muitos projetos e produtos de dados dependem de dados georreferenciados, isto é, informações que estão relacionadas a localizações reais no Globo Terrestre. Por exemplo, utilizamos dados desse tipo para explorar as diferenças de renda entre regiões de uma cidade, definir pontos focais para campanhas de marketing ou criar um modelo de precificação de imóveis.

Ao fim desse artigo você saberá:

  • Quais os formatos de arquivos mais comuns para armazenamento de Dados Georreferenciados (e como importá-los utilizando o Geopandas)
  • Como manipular esse tipo de dados para extrair informações relevantes como áreas e distâncias e entender o papel das projeções nessa tarefa.
  • Como gerar diversos tipos de gráficos (como choropleth, scatterplots, incluir marcadores personalizados) utilizando Folium para facilitar sua análise.

Importando e manipulando seus dados com Geopandas

Para fazer a importação e manipulação dos dados vamos utilizar a biblioteca GeoPandas.

Da documentação (adaptação do autor)

GeoPandas é um projeto Open Source que adiciona funcionalidades de Dados Georreferenciados a objetos Pandas.

A biblioteca adiciona os objetos do tipo GeoSeries e GeoDataFrames que são subclasses dos já conhecidos pandas.Series e pandas.DataFrame, respectivamente.

Os objetos GeoPandas podem servir para realizar operações geométricas em objetos geométricos dos tipos suportados pelo Shapely (Linhas, Polígonos, Multi-Polígonos, Pontos..).

Além disso, utilizar os objetos implementados pelo GeoPandas torna muito mais fácil a tarefa de criar visualizações para seus dados, como vamos ver mais adiante.

Formatos de arquivos

Como são estruturas de dados bastante específicas, os dados georreferenciados costumam aparecer em tipos especiais de arquivos.

Alguns deles são:

  • Shapefiles: é o formato mais comum para armazenamento de dados geográficos e não-geográficos. Na verdade é um conjunto de arquivos que são armazenados no mesmo diretório para leitura (.shp, .shx, .dbf, .prj), sendo o .shp o arquivo para importação.
  • GeoJson: um JSON especial que armazena tanto os dados geográficos quanto os dados não-geográficos (relacionados aos anteriores). Basicamente elimina a dependência de diversos arquivos dos shapefiles. Além disso, algumas bibliotecas dependem desse formato para criar visualizações.
  • GeoPackage: tipo de arquivo relativamente mais leve e rápido de trabalhar do que GeoJSONs e Shapefiles. Podem conter tantos as informações geográficas e não-geográficas e com menos limitações.

Aqui um artigo (em inglês) explicando um pouco das diferenças de Shapefiles/GeoJsons e Geopackages, e quais as vantagens de utilizarmos Geopackage para armazenamento de dados georreferenciados.

Importando os Dados

Primeiro fazemos a leitura do arquivo Geopackage da cidade de São Paulo (disponível no site do IBGE):

Nota: Originalmente o IBGE disponibiliza os dados em SHP, mas optei por convertê-los para Geopackage, pelos benefícios deste.

A conversão foi feita no próprio GeoPandas da seguinte maneira:

Como podemos ver, o arquivo importado é um ‘GeoDataFrame’ contendo uma coluna com a geometria (‘geometry’ é o padrão da biblioteca) que corresponde as localizações relativas de cada linha do dataframe (nesse caso, setores censitários definidos pelo IBGE) e outras informações (TIPO, NM_BAIRRO etc..).

Cada setor censitário contém uma geometria, que nada mais é do que um conjunto de Pontos que definem um Polígono:

O próprio GeoDataFrame já contém um método plot, o qual identifica as localizações na coluna ‘geometry’ e gera uma visualização bastante simples:

Como citado anteriormente, um GeoDataFrame pode ser manipulado igual um pandas.DataFrame. Por exemplo, podemos filtrar apenas os setores censitários da cidade de Osasco e criar o plot novamente:

CRS: Coordinate Reference System (Sistema de Referência de Coordenadas)

Um ponto importante a se considerar quando trabalhamos com dados geográficos é o Sistema de Referência de Coordenadas (referenciado pelo seu acrônimo em inglês CRS) utilizado.

Ao longo da história muitos estudiosos trataram da difícil tarefa de representar o planeta Terra e suas diversas localidades em um plano 2D, facilitando a navegação e divulgação do conhecimento por meio de mapas. Mas como todos eles descobriram, a tarefa não é nada trivial: aqui um vídeo da Vox muito legal que ilustra essa tarefa díficil.

Lista incompleta de sistemas de coordenadas geográficas (fonte)

Para resumir, quando tentamos criar um plano a partir de uma esfera temos que fazer concessões: em alguns casos as áreas reais se mantêm, mas as formas ficam deformadas. Em outros, as formas são preservadas mas as áreas são grandemente distorcidas. Outros mantêm essas duas propriedades, mas as posições relativas se perdem, ou criam mapas bastante desagradáveis esteticamente.

Ou seja, todas as projeções ‘estão completamente erradas’, mas acertam em alguns pontos. O importante é escolher a projeção correta para seu caso de uso.

Por que você precisa saber disso?

Bom, em primeiro lugar, cada fonte de dados pode disponibilizar os dados geográficos em uma das muitas projeções disponíveis, alterando drasticamente a análise que se pretende fazer.

Por exemplo:

  • EPSG: 4674 é o CRS utilizado pelo IBGE no arquivo que acabamos de abrir
  • EPSG: 4326 é o CRS utilizado pelo Google Earth e se refere a localização no Globo Terrestre (medido em graus)
  • EPSG: 3857 é o CRS utilizado pelo Google Street Maps e se refere a localizações num plano (projeção do Globo) e é medido em metros.

Se, por exemplo, quisermos extrair uma área ou distância entre dois setores censitários em nosso dataset que está em EPSG: 4674:

A própria biblioteca nos informa que, devido a projeção utilizada, medidas de área/distância podem ser imprecisas (além de difíceis de converter para medidas usuais como m² ou km²).

Vamos utilizar o método to_crs() para converter para a mesma projeção utilizada pelo Google Street Maps (EPSG: 3857):

Comparando ambos os resultados vemos que as grandezas são bastante diferentes entre a projeção utilizada pelo IBGE, e aquela utilizada pelo Google Street Maps. Agora temos área e distância em metros e metros quadrados, respectivamente.

Visualizando seus dados com Folium

Folium é uma biblioteca de Python para criação de mapas a partir de dados georreferenciados. Por trás dos panos, Folium se utiliza do módulo ‘leaflet.js’ do JavaScript tornando seus mapas interativos.

Importando a biblioteca e objetos/métodos necessários

Antes de criar nosso primeiro gráfico vamos incluir algumas informações qualitativas provenientes do Censo de 2010 do IBGE (renda, número de domicilios, etc ..) ao nosso GeoDataFrame (osasco_city ):

Criando ‘Mapa de Base’

Quando estamos trabalhando com o Folium, a primeira coisa que faremos é criar um ‘mapa de base’, isto é, uma camada que ajude a identificar as localidades que estamos buscando analisar:

Note que definimos o parâmetro location através das coordenadas (latitude, longitude) próximos de Osasco (center) de forma que o mapa já fosse renderizado com foco nesse ponto. O parâmetro zoom_start define o Zoom inicial do mapa, o qual pode ser alterado interativamente.

Exemplo de ‘mapa de base’ — Stamen Toner

Podemos alterar o parâmetro tiles para obter outros mapas de base:

Exemplo de ‘mapa base’ — Open Street Maps

tiles disponíveis:

  • “OpenStreetMap”
  • “Mapbox Bright” (Limited levels of zoom for free tiles)
  • “Mapbox Control Room” (Limited levels of zoom for free tiles)
  • “Stamen” (Terrain, Toner, and Watercolor)
  • “Cloudmade” (Must pass API key)
  • “Mapbox” (Must pass API key)
  • “CartoDB” (positron and dark_matter)

Fonte: documentação do Folium

Adicionando informações: Marcadores

Após criarmos nossa camada base, podemos começar a adicionar as visualizações que desejarmos. Por exemplo, podemos adicionar marcadores (‘markers’) indicando qualquer informação que desejarmos, desde que tenhamos a localização dos pontos em mãos.

No nosso caso extremamente simples, vamos incluir marcadores para os ‘Centroides’ de cada setor censitário:

Em seguida vamos construir os marcadores com base na (latitude, longitude) do centroide e adicionar cada marcador ao nosso mapa base (m_open_street).

Centroides de setores censitários da cidade de Osasco

Clusterização dos Marcadores

Nossa visualização ficou bastante poluída dado o volume de pontos incluídos. Felizmente estamos trabalhando com uma biblioteca que cria plots interativos e que nos permite agrupar (clusterizar) nossos marcadores:

Desta vez, ao invés de adicionar cada Marker diretamente ao nosso mapa base nós adicionamos ao nosso MarkerCluster e adicionamos este ao mapa. De onde obtemos o seguinte mapa:

GIF ilustrativo do `MarkerCluster`

Mapas Temáticos: Choropleth

Um Mapa ‘Choropleth’ é um tipo de mapa temático em que um conjunto de áreas pré-definidas são coloridas segundo uma estatística. Esse tipo de gráfico é ideal para quando queremos comparar o valor de certa estatística entre regiões.

Por exemplo, o código abaixo nos permite criar uma visualização do valor da renda média de cada setor censitário da cidade de Osasco:

Antes de criar o Choropleth note que nós criamos um novo mapa de base (m_stamen_2) de forma que as camadas anteriores não se sobrepusessem.

Agora vamos entender os parâmetros para criar a visualização de Choropleth:

  • geo_data: Um GeoJson contendo os limites das áreas a serem coloridas. No nosso caso, estamos utilizando um GeoDataFrame (osasco_city) e utilizamos o método __geo_interface__ para gerar o GeoJson a partir dele
  • data: dataframe contendo as informações que queremos visualizar (renda_media) e uma chave de ligação com o geo_json (CD_GEOCODI)
  • columns: identifica as colunas citadas acima (por nome)
  • key_on: caminho do identificador da área no Geojson. No nosso caso, é o campo ‘CD_GEOCODI’ contido dentro de ‘properties’ no Geojson.

Outros parâmetros:

  • fill_color: aqui pode ser uma cor (como ‘blue’), um codigo hex ou, no nosso caso, uma paleta de cores (como ‘PuRu’)
  • fill_opacity: grau de opacidade da cor/paleta definido acima
  • legend_name: nome para identificar a legenda (canto superior direito)

Para entender outros parâmetros para personalização do seu Choropleth ou para entender mais a fundo alguns desses basta acessar a documentação do Folium (ou especificamente do Choropleth).

Por fim, pode ser que algumas das suas necessidades com visualizações de dados não foram retratadas aqui. Recomendo fortemente que dê uma lida na documentação do Folium ou então busque no Plotly, que também possui diversas funcionalidades parecidas e que não estão presentes na primeira.

O mundo de exploração e visualização de dados geográficos é bastante amplo, meu objetivo não era me aprofundar em nenhum assunto específico, mas trazer uma visão geral (mas facilmente aplicável) de como começar a trabalhar com esses dados.

Caso tenha dúvidas e sugestões ou interesse em algum assunto que porventura não me aprofundei aqui fique a vontade para me contatar 😉.

--

--