1.1 Introdução¶

Bases de dados:

Tabela com os PIBs (Produto Interno Bruto) dos estados brasileiros no período de 2002 - 2020

Tabela com a pontuação do IDEB (Índice de Desenvolvimento da Educação Básica) das escolas à nivel nacional

A cada aula, vamos passar por uma base de dados e tecer nossas análises de acordo com as perguntas que forem apresentadas buscando respondê-las por meio da utilização de recursos visuais (gráficos e elementos visuais).

In [1]:
# Definindo a paleta de cores
AZUL1, AZUL2, AZUL3, AZUL4, AZUL5, AZUL6 = '#174A7E', '#4A81BF', "#6495ED", '#2596BE', '#94AFC5', '#CDDBF3'
CINZA1, CINZA2, CINZA3, CINZA4, CINZA5, BRANCO = '#231F20', '#414040', '#555655', '#A6A6A5', '#BFBEBE', '#FFFFFF'
VERMELHO1, VERMELHO2, LARANJA1 = '#C3514E',	'#E6BAB7',	'#F79747'
VERDE1, VERDE2, VERDE3 = '#0C8040',	'#9ABB59', '#9ECCB3'

Situação-problema 1¶

Você como cientista de dados recebeu um conjunto de dados para analisar a composição do PIB em relação aos estados do Brasil durante o período de 2002-2020. Os dados descrevem os valores do PIB e os valores agregados a ele anualmente por setores como agropecuária, indústria, serviços e outros.

Aqui, vamos focar em investigar a composição dos dados em relação aos estados e regiões e tecer alguns comentários a respeito das perguntas levantadas.

In [2]:
import pandas as pd
In [3]:
# Importando a base de dados com o PIB dos estados brasileiros de 2002 a 2020
df_pib = pd.read_csv("https://raw.githubusercontent.com/afonsosr2/dataviz-graficos-composicao-relacionamento/master/dados/pib_br_2002_2020_estados.csv")
df_pib
Out[3]:
ano sigla_uf regiao pib impostos_liquidos va va_agropecuaria va_industria va_servicos va_adespss
0 2002 RO Norte 7467629886 839731192 6627898698 715526872 1191090432 2484579193 2236702207
1 2003 RO Norte 9425010486 1108434936 8316575548 1278658831 1216605061 3376727040 2444584625
2 2004 RO Norte 11004641436 1288806654 9715834778 1288515348 1674933817 3986529419 2765856199
3 2005 RO Norte 12511821181 1476144194 11035676990 1342222120 1887932121 4603783904 3201738843
4 2006 RO Norte 13054713344 1613809974 11440903374 1238006193 2210692147 4320526746 3671678293
... ... ... ... ... ... ... ... ... ... ...
508 2016 DF Centro-Oeste 235540044811 29145619376 206394425435 820754661 9662357225 103859865830 92051447720
509 2017 DF Centro-Oeste 244722249337 29120461647 215601787690 828313642 8448768236 108322119432 98002586380
510 2018 DF Centro-Oeste 254817204692 28692287369 226124917323 1022690641 9541298290 113768086938 101792841454
511 2019 DF Centro-Oeste 273613711477 30686607647 242927103829 992393584 9453608031 125261853488 107219248727
512 2020 DF Centro-Oeste 265847334003 25466227775 240381106228 1623976909 10942472569 116547655370 111267001381

513 rows × 10 columns

In [4]:
# Verificando os tipos de dados e se existem dados nulos
df_pib.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 513 entries, 0 to 512
Data columns (total 10 columns):
 #   Column             Non-Null Count  Dtype 
---  ------             --------------  ----- 
 0   ano                513 non-null    int64 
 1   sigla_uf           513 non-null    object
 2   regiao             513 non-null    object
 3   pib                513 non-null    int64 
 4   impostos_liquidos  513 non-null    int64 
 5   va                 513 non-null    int64 
 6   va_agropecuaria    513 non-null    int64 
 7   va_industria       513 non-null    int64 
 8   va_servicos        513 non-null    int64 
 9   va_adespss         513 non-null    int64 
dtypes: int64(8), object(2)
memory usage: 40.2+ KB

** Houve uma significativa mudança na distribuição do PIB por região comparando os valores de 2002 e 2020?¶

Tratando os dados para gerar a visualização¶

In [5]:
# Criando um df com os dados desejados
df_pib_2002 = df_pib.query("ano == 2002")[["regiao","pib"]]
df_pib_2020 = df_pib.query("ano == 2020")[["regiao","pib"]]

df_pib_2002 = df_pib_2002.groupby("regiao").sum().sort_values("pib", ascending=False)
df_pib_2020 = df_pib_2020.groupby("regiao").sum().sort_values("pib", ascending=False)

display(df_pib_2002, df_pib_2020)
pib
regiao
Sudeste 854309793369
Sul 241564819092
Nordeste 194847656440
Centro-Oeste 128162640832
Norte 69902366306
pib
regiao
Sudeste 3952694729239
Sul 1308147455374
Nordeste 1079331030689
Centro-Oeste 791250735824
Norte 478173048893

Gerando o gráfico¶

In [6]:
## Configurando o gráfico com parâmetros que potencializam a visualização dos dados

# Importando as bibliotecas
import matplotlib.pyplot as plt

# Área do gráfico e tema da visualização
fig, axs = plt.subplots(1, 2, figsize=(14,6))

# Definindo as cores do gráfico
cores = [AZUL3, LARANJA1, AZUL5 , VERDE1, CINZA5]

# Personalizando o gráfico
plt.suptitle('Produto Interno Bruto (PIB) por região', fontsize=18, color=CINZA1, ha = 'right', x = 0.5, y = 1.05)

# GRÁFICO 1 - PIB de 2002 por região
ptc, text, _ = axs[0].pie(data = df_pib_2002, x = "pib", labels = df_pib_2002.index, autopct="%.1f%%",
                          pctdistance=0.6, textprops={"size": 12, "fontweight":"bold", "color": BRANCO},
                          colors = cores)

# Título do Gráfico 1
axs[0].annotate("Em 2002", xy=(50, 350), size =12, xycoords='axes points',
            bbox=dict(boxstyle="round", fc=BRANCO, ec=CINZA3))

# Ajustando as cores das regiões relativas as fatias
for i, p in enumerate(ptc):
  text[i].set_color(p.get_facecolor())

#######################################

# GRÁFICO 2 - PIB de 2020 por região
ptc, text, _ = axs[1].pie(data = df_pib_2020, x = "pib", labels = df_pib_2020.index, autopct="%.1f%%",
                          pctdistance=0.6, textprops={"size": 12, "fontweight":"bold", "color": BRANCO},
                          colors = cores)

# Título do Gráfico 2
axs[1].annotate("Em 2020", xy=(50, 350), size =12, xycoords='axes points',
            bbox=dict(boxstyle="round", fc=BRANCO, ec=CINZA3))

# Ajustando as cores das regiões relativas as fatias
for i, p in enumerate(ptc):
  text[i].set_color(p.get_facecolor())

#######################################

axs[0].annotate('A Região Sudeste foi a única que\nreduziu a participação no PIB',
            xy=(180, 245), xycoords='axes points', xytext=(280, 295), textcoords='axes points',
            bbox=dict(boxstyle="round", fc=BRANCO, ec=CINZA3),
            size=10, arrowprops=dict(arrowstyle="->", fc=CINZA1, connectionstyle="arc,angleA=-90,angleB=0,armA=30,armB=30,rad=5"))

axs[1].annotate('\n\n', xy=(140, 245), xycoords='axes points', xytext=(-50, 295), textcoords='axes points',
            size=10, arrowprops=dict(arrowstyle="->", fc=CINZA1, connectionstyle="arc,angleA=-90,angleB=0,armA=30,armB=-30,rad=5"))

plt.show()

Conclusões:


Aqui notamos um uso correto de gráfico de pizza que trouxemos 5 fatias no total. Tecemos uma comparação entre dois períodos separadamente, visto que o gráfico de pizza representa composições estáticas.

Podemos notar que apenas a região Sudeste recuou em participação no PIB no período que abrange 18 anos (2002 - 2020). Ou seja, foi possível notar que o PIB foi mais distribuído. Podemos perceber esse comportamento sem nem precisar analisar os dados absolutos, apenas os relativos.

Como sugestão, podemos testar adicionando os valores absolutos do PIB das regiões ou fazer essa análise em uma região em específico como por exemplo, a região Sul do Brasil (3 estados apenas).

** Qual a participação do estado de Minas Gerais no PIB de todo o Brasil no ano de 2020?¶

Tratando os dados para gerar a visualização¶

In [7]:
# Criando um df com os dados desejados
df_mg_2020 = df_pib.query("ano == 2020")[["sigla_uf", "pib"]]

# Renomeando todos os estados como 'Outros' e mudando da sigla MG para Minas Gerais
df_mg_2020.loc[df_mg_2020["sigla_uf"] == "MG", "sigla_uf"] = "Minas Gerais"
df_mg_2020.loc[df_mg_2020["sigla_uf"] != "Minas Gerais", "sigla_uf"] = "Outros"

df_mg_2020 = df_mg_2020.groupby("sigla_uf").sum()
df_mg_2020
Out[7]:
pib
sigla_uf
Minas Gerais 682786116407
Outros 6926810883612

Gerando o gráfico¶

In [8]:
## Configurando o gráfico com parâmetros que potencializam a visualização dos dados

# Importando as bibliotecas
import matplotlib.pyplot as plt

# Área do gráfico e tema da visualização
fig, ax = plt.subplots(figsize=(6,6))

# Definindo as cores do gráfico
cores = [AZUL3, CINZA5]

# Personalizando o gráfico
plt.suptitle('PIB de Minas Gerais em relação ao Brasil em 2020', fontsize=18, color=CINZA1, ha = 'left', x = 0, y = 0.9)

# Gerando o gráfico do PIB de 2020 de Minas Gerais em relação a todo Brasil
ptc, text, _ = ax.pie(data = df_mg_2020, x="pib", labels=df_mg_2020.index, autopct = "%.1f%%",
                      startangle = 0, pctdistance = 0.8, wedgeprops=dict(width=0.4),
                      textprops=dict(size=12, fontweight="bold", color= BRANCO),
                      colors = cores)

# Ajustando as cores das regiões relativas as fatias
for i, p in enumerate(ptc):
  text[i].set_color(p.get_facecolor())

plt.show()

Conclusões:


O gráfico de rosca apresenta a melhor forma de utilizarmos os gráficos de pizza e rosca numa visualização: comparando dados binários ou dicotômicos. Aqui, fizemos a comparação do PIB de Minas Gerais em relação a todo o Brasil no ano de 2020.

Como sugestão, podemos analisar o seu próprio estado ou aquele que tenha interesse em comparar com o Brasil inteiro ou até uma região pelo todo em um dado ano.

** Como está distribuído o PIB do estado da Bahia em 2020 separado por impostos líquidos e os valores adicionados brutos dos bens e serviços produzidos?¶

Tratando os dados para gerar a visualização¶

In [9]:
bahia = df_pib.query("sigla_uf == 'BA' and ano == 2020")[["pib","impostos_liquidos", "va"]]
bahia.rename(columns = {"pib":"PIB", "impostos_liquidos": "Impostos Líquidos", "va":"Valor Adicionado Bruto"}, inplace=True)
bahia
Out[9]:
PIB Impostos Líquidos Valor Adicionado Bruto
303 305320812691 37094030606 268226782074
In [10]:
# Criando um df com os dados desejados
bahia = bahia.melt(var_name = "Indicadores", value_name = "Valores")

bahia
Out[10]:
Indicadores Valores
0 PIB 305320812691
1 Impostos Líquidos 37094030606
2 Valor Adicionado Bruto 268226782074
In [11]:
# Alterando os impostos para descréscimo, criando uma coluna com os valores em string e outra com as medidas
bahia.loc[bahia["Indicadores"] == "Impostos Líquidos", "Valores"] = bahia["Valores"] * -1
bahia["Valores_str"] = (bahia["Valores"]/1e9).map("R$ {:,.2f} Bi".format)
bahia["Medidas"] = ["absolute", "relative", "total"]

bahia
Out[11]:
Indicadores Valores Valores_str Medidas
0 PIB 305320812691 R$ 305.32 Bi absolute
1 Impostos Líquidos -37094030606 R$ -37.09 Bi relative
2 Valor Adicionado Bruto 268226782074 R$ 268.23 Bi total

Gerando o gráfico¶

In [12]:
## Configurando o gráfico com parâmetros que potencializam a visualização dos dados

# Importando as bibliotecas
import plotly.graph_objects as go

# Gerando o gráfico de cascata
fig = go.Figure( go.Waterfall(name = "", orientation = "v", measure = bahia["Medidas"],
                             x = bahia["Indicadores"],  y = bahia["Valores"],
                             text = bahia["Valores_str"], textposition = "outside",
                             connector_line = dict(color = CINZA3),
                             totals_marker = dict(color = AZUL3),
                             decreasing_marker = dict(color = VERMELHO1)
                             )
              )

# Personalizando o gráfico
fig.update_layout(width=1000, height=500, font_family = 'DejaVu Sans', font_size=15,
                  font_color= CINZA2, title_font_color= CINZA1, title_font_size=24,
                  title_text='Distribuição do Produto Interno Bruto (PIB) da Bahia em 2020' +
                             '<br><sup size=1 style="color:#555655">Impostos líquidos e Valores ' +
                              'Adicionados Brutos de bens e serviços (em bilhões de reais)</sup>',
                  title_pad_l = 50, plot_bgcolor= BRANCO, yaxis_range=[0,380e9], hovermode="closest")

# Retirando os ticks do eixo y
fig.update_yaxes(showticklabels=False)

# Dados ao passar o mouse
fig.update_traces(hovertemplate = "<b>%{x}</b> = %{text}")

fig.add_annotation(text='Fonte dos dados: <a href="https://sidra.ibge.gov.br/pesquisa/pib-munic/tabelas">Produto Interno Bruto | IBGE</a>',
                   align="left", xref="paper", yref = "paper", x=1, y=-0.2, showarrow=False)

fig.show()

Conclusões:


Um gráfico de cascata é aplamente utilizado em dados econômicos e financeiros por sua natureza de representar de maneira simples e direta a acumulação e /ou subtração do total em determinado período ou em diferentes categorias.

Como sugestão, podemos analisar esses valores do seu próprio estado ou até separar os valores adicionados por tipo de serviço mostrando a agregação de cada um.

Observação: Para auxiliar na compreensão do gráfico, os bens e serviços finais que compõem o PIB são medidos no preço em que chegam ao consumidor. Dessa forma, levam em consideração também os impostos sobre os produtos comercializados.

2.2 - Adicionando mais acréscimos/decréscimos¶


** Qual a evolução anual do PIB do estado do Rio de Janeiro entre os anos de 2010 a 2020?¶

Tratando os dados para gerar a visualização¶

In [17]:
# Selecionando os dados do RJ
anos = [x for x in range(2010, 2021)]
rio = df_pib.query("sigla_uf == 'RJ' and ano == @anos")[["ano", "pib"]]
rio = rio.reset_index(drop=True)
rio
Out[17]:
ano pib
0 2010 449858101109
1 2011 512767904769
2 2012 574884973130
3 2013 628226069362
4 2014 671076844311
5 2015 659138951833
6 2016 640401206447
7 2017 671605668055
8 2018 758859046865
9 2019 779927917084
10 2020 753823710636
In [18]:
# Gerando uma coluna com a variação do pib e passando o valor
# do PIB inicial para a 1ª linha da variação pib
rio["variacao_pib"] = rio["pib"].diff().fillna(rio["pib"]).astype("int64")

# Gerando uma coluna com as Medidas para o gráfico de cascata
rio["Medidas"] = ["absolute"] + ["relative"] * 10

rio.head()
Out[18]:
ano pib variacao_pib Medidas
0 2010 449858101109 449858101109 absolute
1 2011 512767904769 62909803660 relative
2 2012 574884973130 62117068361 relative
3 2013 628226069362 53341096232 relative
4 2014 671076844311 42850774949 relative
In [19]:
# Gerando uma observação com a atualização da última linha com o PIB total de 2020
atualizacao = pd.Series({'ano': 'Total',
                         'pib': rio["pib"].values[-1],
                         'variacao_pib': rio["pib"].values[-1],
                         'Medidas': "total"}).to_frame().T

# Concatenando o df com a atualização e retirando a coluna pib
rio = pd.concat([rio, atualizacao], axis = 0, ignore_index=True)
rio = rio.drop(columns=["pib"])

# Ajustando a formatação do PIB e renomeando colunas
rio["variacao_pib_texto"] = (rio["variacao_pib"]/1e9).map('R$ {:,.2f} Bi'.format)
rio.rename(columns = {"ano":"Ano", "variacao_pib": "Variação do PIB", "variacao_pib_texto":"Variação do PIB (em texto)"}, inplace=True)
rio
Out[19]:
Ano Variação do PIB Medidas Variação do PIB (em texto)
0 2010 449858101109 absolute R$ 449.86 Bi
1 2011 62909803660 relative R$ 62.91 Bi
2 2012 62117068361 relative R$ 62.12 Bi
3 2013 53341096232 relative R$ 53.34 Bi
4 2014 42850774949 relative R$ 42.85 Bi
5 2015 -11937892478 relative R$ -11.94 Bi
6 2016 -18737745386 relative R$ -18.74 Bi
7 2017 31204461608 relative R$ 31.20 Bi
8 2018 87253378810 relative R$ 87.25 Bi
9 2019 21068870219 relative R$ 21.07 Bi
10 2020 -26104206448 relative R$ -26.10 Bi
11 Total 753823710636 total R$ 753.82 Bi

Gerando o gráfico¶

In [20]:
## Configurando o gráfico com parâmetros que potencializam a visualização dos dados

# Importando as bibliotecas
import plotly.graph_objects as go
import numpy as np

# Gerando o gráfico de cascata
fig = go.Figure(
                go.Waterfall(name = "", orientation = "v", measure = rio["Medidas"],
                             y = rio["Variação do PIB"], text = rio["Variação do PIB (em texto)"],
                             textposition = "outside",
                             connector_line = dict(color = CINZA3),
                             totals_marker = dict(color = AZUL3),
                             increasing_marker = dict(color = VERDE1),
                             decreasing_marker = dict(color = VERMELHO1)
                             )
                )

# Personalizando o gráfico
fig.update_layout(width=1300, height=600, font_family = 'DejaVu Sans', font_size=15,
                  font_color= CINZA2, title_font_color= CINZA1, title_font_size=24,
                  title_text='Variação do Produto Interno Bruto (PIB) do Rio de Janeiro' +
                             '<br><sup size=1 style="color:#555655">De 2010 a 2020 (em bilhões de reais)</sup>',
                  plot_bgcolor= BRANCO, yaxis_range=[0,850e9])

# Retirando os ticks do eixo y
fig.update_yaxes(showticklabels=False)

# Ajustando o eixo x para receber o Total
fig.update_xaxes(tickmode='array', tickvals=np.arange(0,12), ticktext=rio["Ano"])

# Dados ao passar o mouse
fig.update_traces(hovertemplate = "<b>%{x}</b> = %{text}")

fig.add_annotation(text="O <b>Rio de Janeiro</b> apresentou recuo no PIB<br>em pelo menos 3 anos no período:<br>2015, 2016 e 2020",
                   align="left", axref = 'x', ayref='y', x=5, y=600e9, ax=8, ay=450e9,
                   arrowhead=1, arrowside = "start", showarrow=True, arrowwidth=2, arrowcolor=CINZA3,
                   bordercolor= CINZA3, borderwidth=1, borderpad=4)
fig.add_annotation(text="", axref = 'x', ayref='y', x=6, y=600e9, ax=8, ay=530e9,
                   arrowhead=1, arrowside = "start", showarrow=True, arrowwidth=2, arrowcolor=CINZA3)
fig.add_annotation(text="", axref = 'x', ayref='y', x=10, y=710e9, ax=8.5, ay=530e9,
                   arrowhead=1, arrowside = "start", showarrow=True, arrowwidth=2, arrowcolor=CINZA3)

fig.show()

Conclusões:


Neste exemplo, o gráfico de cascata foi utlilizado para mostrar a evolução do PIB de um estado ano após ano partindo do valor inicial (ano de 2010) até o final (ano de 2020, representado pela coluna Total). É possível notar acréscimos e descréscimos ao longo do tempo, representados pelas cores verde e vermelho, respectivamente.

Como sugestão, podemos analisar a evolução do PIB do seu próprio estado ou de uma região de interesse.

Como está distribuído o PIB nos 3 últimos quinquênios (lustro) dos dados (2010, 2015, 2020) na Região Sul do Brasil divididos pelos estados (Paraná, Santa Catarina e Rio Grande do Sul)?¶

Tratando os dados para gerar a visualização¶

In [21]:
# Selecionando os dados da região Sul do Brasil
anos = [x for x in range(2010, 2021, 5)]
pib_sul = df_pib.query("regiao == 'Sul' and ano == @anos")[["ano", "sigla_uf", "pib"]]
pib_sul["pib"] = (pib_sul["pib"] / 1e9).round(2)
pib_sul = pib_sul.reset_index(drop=True)
pib_sul
Out[21]:
ano sigla_uf pib
0 2010 PR 225.21
1 2015 PR 376.96
2 2020 PR 487.93
3 2010 SC 153.73
4 2015 SC 249.08
5 2020 SC 349.28
6 2010 RS 241.25
7 2015 RS 381.99
8 2020 RS 470.94
In [22]:
# Criando uma tabela cruzada (crosstab) com os valores de venda de cada ano por região
pib_sul_cross = pd.crosstab(index = pib_sul.ano, columns = pib_sul.sigla_uf,
                            values = pib_sul.pib, aggfunc = "sum", normalize = "index")
pib_sul_cross = pib_sul_cross.reset_index()
pib_sul_cross
Out[22]:
sigla_uf ano PR RS SC
0 2010 0.363131 0.388994 0.247876
1 2015 0.373957 0.378947 0.247096
2 2020 0.372992 0.360005 0.267003

Gerando o gráfico¶

In [23]:
## Configurando o gráfico com parâmetros que potencializam a visualização dos dados

# Importando as bibliotecas
import matplotlib.pyplot as plt
import seaborn as sns

# Área do gráfico e tema da visualização
fig, axs = plt.subplots(1, 2, figsize=(16,6))
sns.set_theme(style="white")

# Definindo as cores do gráfico
cores = [AZUL6, VERDE3, VERMELHO2]

# Personalizando o Título superior
fig.suptitle("Distribuição do PIB na região Sul do Brasil por quinquênio (2010 - 2020)",
             fontsize=18, color=CINZA1, ha = 'right', x = 0.66, y = 1.05)

# GRÁFICO 1 - Gráfico de colunas agrupadas
sns.barplot(data = pib_sul, x = "ano", y = "pib", hue = "sigla_uf", hue_order = ["PR", "RS", "SC"], ax = axs[0], palette = cores)

axs[0].set_title('Em bilhões de reais\n', color = CINZA3, loc = "left")
axs[0].set_xlabel('')
axs[0].set_ylabel('')
axs[0].xaxis.set_tick_params(labelsize=14, color = CINZA2)
axs[0].yaxis.set_tick_params(labelsize=14, color = CINZA2)
axs[0].set_frame_on(False)

# Remover a legenda e colocar grids no eixo y
axs[0].legend().remove()
axs[0].yaxis.grid(linestyle='--', linewidth=1)

#######################################

# GRÁFICO 2 - Gráfico de colunas empilhadas 100 %
pib_sul_cross.plot(x = "ano", kind="bar", stacked = True, color = cores, ax = axs[1])

axs[1].set_title('Em porcentagem\n', color = CINZA3, loc = "left")
axs[1].set_xlabel('')
axs[1].set_ylabel('')
axs[1].set_yticklabels([])
axs[1].xaxis.set_tick_params(labelsize=14, color = CINZA2, labelrotation = 0)
axs[1].set_frame_on(False)

# Adicionar a legenda entre os dois gráficos
axs[1].legend(bbox_to_anchor=(-0.005, 1), title='Estado', title_fontsize  = 12, fontsize = 12)

#######################################

# Adicionando os valores dentro da coluna
for container in axs[1].containers:
    labels = [f'{valor.get_height()*100:.0f}%' for valor in container]
    axs[1].bar_label(container, label_type='center', labels = labels, size = 11, color = CINZA3, fontweight = "bold")

plt.show()

Conclusões:


Neste exemplo, apresentamos as diferenças entre colunas agrupadas e empilhadas. A 1ª reflete os valores absolutos do PIB em cada estado da Região Sul por quinquênio (lustro), já a 2ª representa os valores relativos compilados ano a ano da região como um todo.

** Como estão distribuídos, em porcentagem, os valores adicionados de bens e serviços descritos na base de dados em relação a cada região no ano de 2020?¶

Tratando os dados para gerar a visualização¶

In [24]:
# Selecionando os dados desejados
df_va_separado = df_pib.query("ano == 2020")[["regiao", "va_servicos", "va_industria", "va_adespss", "va_agropecuaria"]]
df_va_separado = df_va_separado.reset_index(drop=True)
df_va_separado.head()
Out[24]:
regiao va_servicos va_industria va_adespss va_agropecuaria
0 Norte 19060688172 8285675423 12000339417 6891411669
1 Norte 6590543336 1191345379 6031050521 983531817
2 Norte 34795836262 35839810630 20210620577 5114449144
3 Norte 5278754961 1706511471 6538065265 1000907462
4 Norte 56395092425 84173852308 37614037902 19730656823
In [25]:
# Agrupando os dados por região
df_va_separado = df_va_separado.groupby("regiao").agg("sum")

# Normalizando os dados de cada região
df_va_separado = df_va_separado.div(df_va_separado.sum(axis=1), axis=0)
df_va_separado = df_va_separado.sort_values(by="va_servicos", axis=0)
df_va_separado
Out[25]:
va_servicos va_industria va_adespss va_agropecuaria
regiao
Norte 0.338521 0.323217 0.239485 0.098777
Centro-Oeste 0.435471 0.153645 0.266185 0.144699
Nordeste 0.459790 0.191011 0.260121 0.089078
Sul 0.508060 0.252751 0.139648 0.099541
Sudeste 0.610871 0.228032 0.133536 0.027561

Gerando o gráfico¶

In [26]:
# Gerando a função para criar o gráfico de barras empilhadas

def grafico_va():
  # Importando as bibliotecas
  import matplotlib.pyplot as plt

  # Área do gráfico e tema da visualização
  fig, ax = plt.subplots(figsize=(10,7))

  # Definindo as cores do gráfico
  cores = [AZUL3, LARANJA1, CINZA5, VERDE3]

  # Gerando o gráfico de barras empilhadas 100%
  df_va_separado.plot(kind="barh", stacked=True, color = cores, ax=ax)

  ## Personalizando o gráfico
  plt.suptitle('Valores adicionados de bens e serviços do PIB brasileiro em 2020', size=18, color=CINZA1, ha = 'right', x = 0.8, y = 1.01)
  plt.title('Em distribuição dos setores por região (%)\n', fontsize=14, color=CINZA3, pad = 15, ha = "right", x = 0.35)
  ax.legend(bbox_to_anchor=(1, 1), bbox_transform=ax.transAxes, fontsize = 10, loc='upper left', )
  ax.set_ylabel('')
  ax.set_xticklabels([])
  ax.yaxis.set_tick_params(labelsize=14, color = CINZA2)
  ax.set_frame_on(False)

  # Valores das barras
  for container in ax.containers:
      labels = [f'{valor.get_width()*100:.0f}%' for valor in container]
      ax.bar_label(container, label_type='center', labels = labels, size = 10, color = CINZA2, fontweight='bold')

  return ax, cores

ax, cores = grafico_va()

Conclusões:

As barras empilhadas são extremamente úteis para representação dos dados em pequenos períodos e quando desejamos comparar diferenças absolutas e relativas ou apenas relativas (como no exemplo acima).

Como sugestão, podemos analisar a composição dos dados em relação aos setores de uma dada região, separada pelos estados.

Pergunta 8 - Na agropecuária, como estão distribuídos seus valores adicionados por região dentro do período da base dos dados (2002 - 2020)?¶

In [27]:
# Selecionando os dados desejados
df_agro = df_pib.copy()
df_agro = df_agro[["regiao", "ano", "va_agropecuaria"]]

# Agrupando os dados por região
df_agro = pd.crosstab(index = df_agro.ano, columns = df_agro.regiao,
                      values = df_agro.va_agropecuaria, aggfunc="sum")
df_agro = (df_agro / 1e9).round(2)

df_agro.head()
Out[27]:
regiao Centro-Oeste Nordeste Norte Sudeste Sul
ano
2002 12.98 17.04 6.40 22.57 22.53
2003 18.70 20.98 8.14 25.71 32.42
2004 20.98 22.44 8.18 28.27 31.05
2005 17.04 22.03 8.53 28.99 24.37
2006 12.15 23.42 8.91 34.44 26.37

gerando gráfico¶

In [28]:
## Configurando o gráfico com parâmetros que potencializam a visualização dos dados

# Importando as bibliotecas
import matplotlib.pyplot as plt

# Área do gráfico e tema da visualização
fig, ax = plt.subplots(figsize=(14,7))

# Definindo as cores do gráfico
cores = [VERDE3, VERMELHO2, AZUL3, LARANJA1, CINZA4]

# Gerando o gráfico de áreas empilhadas
df_agro.plot(kind="area", stacked=True, color = cores, ax = ax, xticks = range(2002, 2021, 2))

## Personalizando o gráfico
ax.set_title('PIB relativo à agropecuária nas regiões do Brasil', fontsize = 18, color = CINZA1, loc='left')
ax.text(0.29, 0.98, "De 2002 a 2020 (em bilhões de reais)", transform=ax.transAxes, color= CINZA3, fontsize=12, ha='right', va='center')
ax.set_ylabel('')
ax.xaxis.set_tick_params(labelsize=14, color = CINZA2)
ax.legend().remove()
ax.set_frame_on(False)

## Anotando os nomes das regiões
reg = list(reversed(df_agro.columns))
cor = list(reversed(cores))
for i in range(len(reg)):
  ax.text(0.97, (0.67 - i/7), f'{reg[i]}', fontsize=14, color = cor[i], transform=ax.transAxes)

## Ajustes no eixo y
# Descrevendo o limite mínimo e máximo do eixo y e escondendo o eixo
plt.ylim(0, 500)
ax.get_yaxis().set_visible(False)

# remover todos os ticks do eixo x e y
ax.tick_params(axis='both', which='both', length=0)

# Destacando os valores de 4 em 4 anos e no ano de 2020
agregado_ano = list(df_agro.sum(axis=1).round(2))
for i in range(0, len(df_agro.index), 4):
  ax.text(x = df_agro.index[i], y = agregado_ano[i] + 20, s = f"{agregado_ano[i]} Bi", color = CINZA3, weight = "bold", fontsize = 10, ha="center")
ax.text(x = df_agro.index[-1], y = agregado_ano[-1] + 20, s = f"{agregado_ano[-1]} Bi", color = CINZA3, weight = "bold", fontsize = 10, ha="center")

plt.show()

Conclusões:


Os gráficos de áreas são extremamente úteis quando queremos enfatizar a magnitude das mudanças ao longo do período. Ele é uma junção de várias linhas empilhadas preenchidas com a cor de cada categoria para representação dos dados ao longo do período. No exemplo acima, utilizamos o gráfico de áreas em que tanto a diferença absoluta (valores ao longo do tempo) quanto a relativa (espessuras entre elas) são importantes em nossa análise.

Como sugestão, podemos analisar a composição dos dados em relação a outros setores.

- Apresentando a base de dados IDEB¶

Situação-problema 2¶

Nesta situação-problema, você recebeu um conjunto de dados para analisar as notas do IDEB, divididas por região, das provas realizadas entre 2005 e 2021. Os dados descrevem o desempenho dos alunos em testes de língua portuguesa e matemática, além da taxa de aprovação escolar.

O IDEB é medido em uma escala de 0 a 10 e é uma importante ferramenta para acompanhar o desenvolvimento da educação básica no país, permitindo a avaliação da efetividade das políticas públicas na área e a identificação das regiões que necessitam de maior atenção.

Aqui, vamos focar em investigar as notas em diferentes níveis de ensino (Ensino Fundamental Anos Iniciais e Anos Finais e Ensino Médio) tecendo alguns comentários a respeito das perguntas levantadas.

In [30]:
import pandas as pd
In [31]:
ideb = pd.read_csv("https://raw.githubusercontent.com/afonsosr2/dataviz-graficos-composicao-relacionamento/master/dados/ideb_reg_2005_2021.csv")

ideb.head()
Out[31]:
ano regiao rede ensino anos_escolares taxa_aprovacao indicador_rendimento nota_saeb_matematica nota_saeb_lingua_portuguesa nota_saeb_media_padronizada ideb
0 2005 Centro-Oeste estadual fundamental EFAF 72.1 0.721828 233.50 227.88 4.356453 3.1
1 2005 Centro-Oeste estadual fundamental EFAI 83.0 0.837081 185.38 172.13 4.631618 3.9
2 2005 Centro-Oeste estadual medio EM 68.0 0.695138 261.23 251.52 4.123654 2.9
3 2005 Centro-Oeste privada fundamental EFAF 94.4 0.943491 283.57 266.82 5.840183 5.5
4 2005 Centro-Oeste privada fundamental EFAI 97.3 0.972388 223.64 210.36 6.057024 5.9
In [32]:
ideb.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 270 entries, 0 to 269
Data columns (total 11 columns):
 #   Column                       Non-Null Count  Dtype  
---  ------                       --------------  -----  
 0   ano                          270 non-null    int64  
 1   regiao                       270 non-null    object 
 2   rede                         270 non-null    object 
 3   ensino                       270 non-null    object 
 4   anos_escolares               270 non-null    object 
 5   taxa_aprovacao               270 non-null    float64
 6   indicador_rendimento         270 non-null    float64
 7   nota_saeb_matematica         270 non-null    float64
 8   nota_saeb_lingua_portuguesa  270 non-null    float64
 9   nota_saeb_media_padronizada  270 non-null    float64
 10  ideb                         270 non-null    float64
dtypes: float64(6), int64(1), object(4)
memory usage: 23.3+ KB

-** Qual a relação entre o IDEB e o indicador de rendimento das escolas no ensino médio? É positiva, negativa ou não estão correlacionadas?¶

visualizando dados¶

In [34]:
ideb_em = ideb.query("anos_escolares == 'EM'")[["indicador_rendimento", "ideb"]]
ideb_em = ideb_em.reset_index(drop = True)
ideb_em.head()
Out[34]:
indicador_rendimento ideb
0 0.695138 2.9
1 0.943179 5.7
2 0.730819 2.7
3 0.916831 5.2
4 0.737045 2.7
In [35]:
# Importando a biblioteca
import plotly.express as px

# Gerando o gráfico de dispersão com uma reta representando um modelo de regressão linear (OLS - Mínimos Quadrados Ordinários)
fig = px.scatter(ideb_em, x="ideb", y="indicador_rendimento", trendline = 'ols',
                 color_discrete_sequence = [AZUL3], trendline_color_override=CINZA3,
                 labels = {"ideb":"IDEB", "indicador_rendimento":"Indicador de Rendimento"})

# Ajustando o layout do gráfico
fig.update_layout(width=1000, height=500, yaxis_range = [0, 1.1], xaxis_range = [2.5, 7.5],
                  margin = dict(t=100), font_size=14, font_color= CINZA2,
                  title_font_color= CINZA1, title_font_size=24,
                  title_text='Relação entre o IDEB e o indicador de rendimento das escolas' +
                             '<br><sup size=1 style="color:#555655">Do Ensino Médio (EM) entre os anos de 2005 a 2021</sup>',
                  xaxis_title='IDEB (0-10)', yaxis_title='Indicador de Rendimento (0-1)')

# Dados ao passar o mouse
fig.update_traces(hovertemplate = "<b>IDEB:</b> %{x} <br><b>Indicador de Rend:</b> %{y}", selector = dict(type='scatter', mode = "markers"))

fig.add_annotation(text='Fonte dos dados: <a href="https://www.gov.br/inep/pt-br/areas-de-atuacao/avaliacao-e-exames-educacionais/saeb">'
                        'Sistema de Avaliação da Educação Básica (Saeb)</a>',
                   align="left", xref="paper", yref = "paper", x=1, y=-0.15, showarrow=False, font_size=10)
fig.show()

Conclusões:


O gráfico de dispersão pode ser utilizado para relacionar dados entre duas variáveis numéricas de diferentes naturezas. Essa relação pode ser positiva, negativa ou neutra, linear ou não linear.

Aqui traçamos uma reta em volta dos dados que representam a tendência entre eles, similar ao comoportamento que geramos a trabalhar com modelos de regressão linear.

** Qual a relação entre as notas das disciplinas de língua portuguesa e matemática no SAEB por região no Ensino Fundamental Anos Iniciais? Conseguimos traçar algum paralelo entre elas?¶

In [36]:
ideb_efai = ideb.query("anos_escolares == 'EFAI'")[["regiao","nota_saeb_matematica", "nota_saeb_lingua_portuguesa"]]
ideb_efai = ideb_efai.reset_index(drop = True)
ideb_efai.head()
Out[36]:
regiao nota_saeb_matematica nota_saeb_lingua_portuguesa
0 Centro-Oeste 185.38 172.13
1 Centro-Oeste 223.64 210.36
2 Nordeste 162.61 156.61
3 Nordeste 211.16 199.88
4 Norte 166.39 161.30
In [37]:
## Configurando o gráfico com parâmetros que potencializam a visualização dos dados

# Importando as bibliotecas
import matplotlib.pyplot as plt
import seaborn as sns

# Definindo as cores do gráfico
cores = [VERDE3, VERMELHO2, AZUL3, LARANJA1, CINZA4]

# Área do gráfico e tema da visualização
fig, ax = plt.subplots(figsize=(10,5))
sns.set_theme(style="white")

# Gerando o gráfico de dispersão com cores como categorias
ax = sns.scatterplot(data = ideb_efai, x  = "nota_saeb_matematica", y="nota_saeb_lingua_portuguesa", hue = "regiao", palette = cores)

## Personalizando o gráfico
plt.suptitle('Relação entre as notas de matemática e língua portuguesa do SAEB', size=18, color=CINZA1, ha = 'right', x = 0.97, y = 1.03)
plt.title('Do Ensino Fudamental Anos Iniciais (EFAI) entre os anos de 2005 a 2021', fontsize=14, color=CINZA3, pad = 15, loc = "left")
ax.legend(bbox_to_anchor=(155, 275), title='Região', title_fontsize  = 10, fontsize = 10, loc='upper left', bbox_transform=ax.transData)
ax.set_xlabel('Notas de Matemática (0 - 500)',  fontsize = 14)
ax.set_ylabel('Notas de Português (0 - 500)', fontsize = 14)
ax.xaxis.set_tick_params(labelsize=12, color = CINZA2)
ax.set_xlim(150, 280)
ax.yaxis.set_tick_params(labelsize=12, color = CINZA2)
ax.set_ylim(150, 280)
sns.despine()

# Limites das notas em no eixo y (notas de português) - 200 pontos (proficiência)
ax.text(ax.get_xlim()[0] + 1, 202, 'Nível 4 e superior', fontsize=12, color = CINZA3, va = "bottom")
ax.text(ax.get_xlim()[0] + 1 , 198, 'Nível 4 e inferior', fontsize=12, color = CINZA3, va = "top")
plt.axhline(y = 200, color = CINZA5, linestyle='--')

# Limites das notas em no eixo x (notas de matemática) - 225 pontos (proficiência)
ax.text(223, ax.get_ylim()[1] - 10, 'Nível 5\ne inferior', fontsize=12, color = CINZA3, ha="right")
ax.text(227, ax.get_ylim()[1] - 10, 'Nível 5\ne superior', fontsize=12, color = CINZA3, ha="left")
plt.axvline(x = 225, color = CINZA5, linestyle='--')

# Adicionando um texto explicando a divisão de quadrantes e o que significa
ax.annotate("Cada quadrante representa o nível de proficiência\nde estudantes divididas pelo nível 5 (>=225 pontos)\ne 4 (>=200 pontos)\n\n"
            "Nota-se que o 2º quadrante (Nível 5 e superior em \nmatemática e Nível 4 e superior em português)\n"
            "possuímos as notas com melhores desempenhos \nà nivel nacional", xy=(260, 180), xycoords='data',
            bbox=dict(boxstyle="round", fc=BRANCO, ec=CINZA3),
            xytext=(0, 0), textcoords='offset points')

plt.show()

Conclusões:


O gráfico de dispersão por cores adiciona uma variável categórica a análise (em nosso exemplo, a região).

Para compreender um pouco mais sobre os níveis de proficiência aessar este link. E para entender sobre o nível de aprendizado proficiente acesse este outro link

Aqui utilizamos dois recursos visuais que é o de acercamento (gerado pela delimitação dos níveis das notas de língua portuguesa e matemática) e o de similaridade por meio das cores, representando as categorias dos pontos representados pelas regiões.

In [ ]: