Criando Mapas Interativos e Choropleth Maps com Folium em Python

Gustavo Santos
Data Hackers
Published in
6 min readAug 31, 2020

--

Criar mapas interativos em Python não é um assunto complexo.

Não é mesmo.

Existem diversos pacotes, cada um com seus prós e contras, claro. Mas para este artigo eu escolhi usar o Folium por entender que ele é o pacote mais simples de criar mapas em Python.

Já na segunda parte, vamos aumentar um pouco o nível e criar também mapas com codificação de cores por valor, os chamados choropleth maps.

Criando o Seu Primeiro Mapa

Comece importando o pacote para a sua sessão:

import folium

Para criar o mapa, veja que é tão simples quanto importar o pacote. Use uma linha de código. Tudo o que você precisa fazer é pesquisar no Google a latitude e longitude do seu ponto de interesse. Pesquisei por "Brasilia Latitude Longitude" e o buscador me devolveu o que precisava: "The latitude of Brasilia, the Federal Capital Area, Brazil is -15.793889, and the longitude is -47.882778".

Agora é só plugar no código, definir o nível de zoom que você quer inicializar seu mapa e visualizar. Não se esqueça de incluir o sinal de "-" quando necessário.

# Crie o mapa com a localidade de seu interesse.
m = folium.Map(location=[-15.793889, -47.882778], zoom_start=11)
m

Eis o resultado:

Mapa interativo de Brasília, plotado com o Folium em Python

Um parâmetro interessante de mudar é o tipo de gráfico. Usando o tiles podemos escolher entre 'Stamen Toner', 'Stamen Terrain' ou o padrão 'OpenStreetMap'.

# Mudando o tipo de gráfico
m = folium.Map(location=[-15.793889, -47.882778],
zoom_start=11, tiles= 'Stamen Toner')
m
tiles = 'Stamen Toner': mostra o mapa simples
tiles = 'Stamen Terrain': mostra o relevo

Certo. Mas o fato é que apenas esses mapas não nos trazem muita informação, certo? São apenas o plot de uma área. Então vamos inserir alguns itens para completar nosso mapa.

Criando Marcadores

Sendo um mapa a representação de uma localidade, nada mais lógico do que adicionarmos um ponto de interesse dentro dele, seja um objeto de estudo, uma rota, um ponto comercial etc.

Além disso, quando trabalhamos com mapas em Python, tenha em mente que trabalhamos em camadas. Primeiro criamos o objeto com o plot do ponto de interesse e, então, vamos adicionando camadas sobre esse objeto, como marcadores, por exemplo.

Para inserir um marcador no Folium, usamos o .Marker( ).

# Primeiro criamos o objeto m para o mapa
m = folium.Map(location=[-15.793889, -47.882778], zoom_start=11)
# Depois adicionamos o marcador.
folium.Marker(location=[-15.7589665, -47.879422],
popup='Esplanada dos Ministerios',
icon=folium.Icon(color='red', icon='info-sign')
).add_to(m)
m
Adicionamos um marcador com popup informativo

Podemos também criar um marcador circular, de modo a demarcar um raio ao redor de um determinado ponto.

# Primeiro criamos o objeto m para o mapa
m = folium.Map(location=[-15.7601, -47.8800], zoom_start=14)
# Adicionando o marcador circular
folium.CircleMarker(
location=[-15.7601, -47.8800],
radius=50,
popup='Esplanada dos Ministerios',
color='blue',
fill=True,
fill_color='lightblue'
).add_to(m)

m
Marcador circular com raio ao redor do ponto de interesse.

Ainda podemos deixar o próprio usuário inserir o marcador no ponto de interesse, usando o código a seguir.

# Criando o objeto m para o mapa
m = folium.Map(location=[-15.7601, -47.8800], zoom_start=14)
m.add_child(folium.ClickForMarker(popup='Adicionado pelo Usuario'))
Marcador adicionado pelo usuário. Duplo clique remove o ponto.

Criando Choropleth Maps

Choropleth maps são aqueles que usam diferentes tons de cores para codificar valores quantitativos de uma área.

Em outras palavras, se fizermos um mapa choroplético baseado em quantidade de hospitais por bairros de uma cidade, por exemplo, e definirmos as cores indo do vermelho (poucos) até azul (muitos), quanto maior a quantidade de hospitais num bairro, mais azul seria a sua área. O inverso é verdadeiro, sendo mais vermelho quanto menos hospitais tivermos no local.

O choropleth nada mais é do que uma camada plotada sobre o gráfico do Folium, assim como um marker. É como se você tivesse um mapa de um país e então colocasse por cima dele uma folha de plástico transparente com as mesmas bordas das divisões de estados e fosse colorindo esta camada plástica. Nesse caso, a folha transparente é um arquivo geojson, o qual vai reconhecer as divisões do seu mapa, combina-las com as dele e colori-las.

No exemplo que vamos construir, vou criar um choropleth de dados de desemprego 2012 nos EUA. Sabendo que a nossa divisão será feita por estados, que os dados de desemprego foram medidos por estado, é preciso encontrar um arquivo geojson que tenha a divisão da área dos EUA em estados.

Aqui está o df.head( ):

Cinco primeiras linhas do dataset base do choropleth

Agora, precisamos de um arquivo geojson que traga a divisão dos EUA em estados e que tenha uma coluna com a sigla ou o nome dos estados. Caso nosso geojson tenha nomes, será preciso ajustar nosso dataset df para ter os exatos mesmos nomes antes de plotar o mapa.

Segue nosso arquivo geojson:

Captura de tela de parte do arquivo json

Veja que temos tanto o ID sendo a sigla do estado quanto o properties.name sendo o nome do estado. Neste caso, não precisamos fazer alterações no nosso df, basta usar a sigla. O código a seguir vai fazer a ligação entre a coluna State e o feature.id, depois irá desenhar a forma geométrica do estado sobre o mapa — usando os dados contidos no feature.geometry do arquivo json — e, por fim, vai colorir essa forma com o código de coloração gradual baseado na taxa de desemprego (coluna 'Unemployment').

# URL onde estão os dados
url = 'https://raw.githubusercontent.com/python-visualization/folium/master/examples/data'
# Carregar o arquivo csv a ser plotado
df = pd.read_csv(f'{url}/US_Unemployment_Oct2012.csv')
# Carregar o arquivo json
state_geo = f'{url}/us-states.json'
# Criar o mapa base
m = folium.Map(location=[48, -102], zoom_start=3)
#Criar a camada Choroplet
folium.Choropleth(
geo_data=state_geo,
name='choropleth',
data=df,
columns=['State', 'Unemployment'],
key_on='feature.id',
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.2,
legend_name='Taxa de Desemprego (%)'
).add_to(m)
# Visualizar
m

Entendendo a Camada Choropleth

Para entender e reforçar o funcionamento do Choropleth, vou quebrar por parâmetros a explicação.

  • geo_data = é o seu arquivo json.
  • name = 'choropleth' é o nome da sua camada.
  • data = são os seus dados, o seu dataframe.
  • columns = lista de colunas contidas no seu dataset, sendo a primeira a coluna que vai fazer a ligação com o json (no nosso caso era por sigla de estado, coluna 'States') e a segunda ('Unemployment') é a coluna de onde o folium deve tirar os números para criar a escala de cores.
  • key_on = coluna importante onde você diz ao folium como fazer a ligação entre a coluna df.States e o json. Usamos feature.id porque no arquivo json vemos que essa combinação (assinalado em vermelho) leva à sigla do estado. Se escolhermos feature.properties.name, teremos o nome do estado.
  • fill_color = cor do choropleth. Escolhi Amarelo indo para o Vermelho. Outras opções: ‘BuGn’, ‘BuPu’, ‘GnBu’, ‘OrRd’, ‘PuBu’, ‘PuBuGn’, ‘PuRd’, ‘RdPu’, ‘YlGn’, ‘YlGnBu’, ‘YlOrBr’.
  • fill_opacity, line_opacity = opacidade da cor de preenchimento e da linha de contorno.
  • legend_name = Nome na legenda de cores.
Choropleth criado com folium: quanto mais vermelho, maior a taxa de desemprego.

Considerações Finais

Durante algum tempo eu busquei alternativas para criar esse tipo de gráficos para um dos meus projetos e, na minha opinião, este foi sem dúvida o mais fácil de criar.

Demorei um pouco a entender como era feita a ligação entre os códigos do .json file e as colunas do seu dataset de análise. Esta foi, para mim, a parte mais desafiadora e até por isso fiz questão de colocar uma sessão a mais no artigo para reforçar esse conceito. Espero que eu tenha deixado mais claro para você.

Entretanto, se você levar desse artigo que os mapas no Folium são criados em camadas; que para criar um Choropleth é preciso que a sua coluna-chave para divisão de área seja igual à que está no arquivo geojson; e que você precisa saber ler o geojson para poder passar o caminho correto que o Folium vai usar para bater ambos os arquivos você entendeu todo o essencial.

Fique também com este excelente link de documentação do Folium Maps, no qual muito desse artigo foi baseado.

if data:
data.science()

Gus

--

--

Gustavo Santos
Data Hackers

Data Scientist. I extract insights from data to help people and companies to make better and data driven decisions. | In: https://www.linkedin.com/in/gurezende/