Visualizing IBGE Maps with Python and Jupyter

by Müller | Nov 15, 2025 | Data Engineer | 0 comments

For those interested in visualizing geographic maps with Python and working with Brazil’s territorial data, this tutorial offers a step-by-step approach. The goal is to extract and visualize the geographic data published by IBGE.

Understanding the packages


from datetime import datetime
import requests
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
  • requests: makes web requests.
  • pandas: data manipulation.
  • geopandas: pandas extension for geographic data.
  • matplotlib: chart visualization.

Extracting the data

IBGE’s geographic files are downloaded directly over HTTP:


arquivos = {
    'brasil': 'https://geoftp.ibge.gov.br/.../BR_Pais_2021.zip',
    'rga':'https://geoftp.ibge.gov.br/.../BR_RG_Intermediarias_2021.zip',
    'rgi':'https://geoftp.ibge.gov.br/.../BR_RG_Imediatas_2021.zip',
    'rgme':'https://geoftp.ibge.gov.br/.../BR_Mesorregioes_2021.zip',
    'rgmi':'https://geoftp.ibge.gov.br/.../BR_Microrregioes_2021.zip',
    'uf': 'https://geoftp.ibge.gov.br/.../BR_UF_2021.zip',
    'mun': 'https://geoftp.ibge.gov.br/.../BR_Municipios_2021.zip'
}

Each file represents a distinct level of territorial division:

  • brasil: country outline.
  • rga: Intermediate Geographic Regions.
  • rgi: Immediate Geographic Regions.
  • rgme: Mesoregions.
  • rgmi: Microregions.
  • uf: Federative Units (states).
  • mun: Municipalities (most detailed level).

for i in arquivos:
    arquivo = i + ".zip"
    print("Downloading:", arquivos[i])
    data = requests.get(arquivos[i])
    with open("./input/"+arquivo, "wb") as file:
        file.write(data.content)

Visualizing Brazilian states


df = gpd.read_file('zip://input/uf.zip')
df.head()

Filtering only the Northeast region:


df[df['NM_REGIAO']=='Nordeste'].plot()

Visualizing municipalities


df = gpd.read_file('zip://input/mun.zip')
mg = df[df['SIGLA'] == 'MG']
udi = df[df['NM_MUN'] == 'Uberlândia']

fig, (ax1, ax2) = plt.subplots(1,2, figsize=(15,10))
mg.plot(ax=ax1, column="NM_MUN", cmap="YlGnBu")
udi.plot(ax=ax2, edgecolor="k")
ax1.set_title('Minas Gerais')
ax2.set_title('Uberlândia')
ax1.set_axis_off()
ax2.set_axis_off()
plt.tight_layout()
plt.show()

A more complex example

Fetching population data through the IBGE API and merging it with the geographic data:


url = "http://servicodados.ibge.gov.br/api/v3/agregados/6579/periodos/2021/variaveis/9324?localidades=N6[N3[31]]"
response = requests.get(url, verify=False)
data = response.json()

municipios_info = data[0]['resultados'][0]['series']
municipios_list = []

for info in municipios_info:
    id = info['localidade']['id']
    nome = info['localidade']['nome']
    municipio, estado = nome.split(" - ")
    populacao = int(info['serie']['2021'])
    municipios_list.append({
        'id': id,
        'municipio': municipio,
        'estado': estado,
        'population': populacao
    })

df_pop = pd.DataFrame(municipios_list)
merged = mg.set_index('CD_MUN').join(df_pop.set_index('id'))

Plotting a thematic map:


vmin, vmax = 0, 500000
fig, ax = plt.subplots(figsize=(10,6))
merged.plot(column='population', cmap='YlGnBu', linewidth=0.8,
            ax=ax, edgecolor='0.8', vmin=vmin, vmax=vmax)
ax.set_title('Population by municipality in Minas Gerais')
plt.show()

Conclusion

With Python, GeoPandas, and IBGE’s public data, it is possible to build powerful geographic visualizations, from state-level analyses to complex thematic maps.

Table of Contents