Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Dataviz Code Session: Séries Temporais

Objetivos da DCS

  • Aplicar técnicas de dataviz para plotagem e manipulação de séries temporais;

  • Manipular séries temporais (STs) relativas a dados de repasses da arrecadação federal efetivados pela Secretaria Especial da Receita Federal do Brasil a outras entidades e fundos;

  • Produzir representações visuais de STs e suas componentes fundamentais (tendência, sazonalidade e ruído);

Ferramentas utilizadas

  • Módulos Python

    • pandas

    • sys

    • matplotlib

    • seaborn

    • statsmodels

    • numpy

Aplicação do modelo referencial

from matplotlib.patches import Patch
from statsmodels.tsa.seasonal import seasonal_decompose

import pandas as pd, matplotlib.pyplot as plt, seaborn as sb, numpy as np
import sys; sys.path.insert(1,'../dcs')
import dcs27

plt.style.use('../etc/gcpeixoto-datavis.mplstyle') # style sheet

Dados de entrada pré-processados

# carrega dados da RFB
df = dcs27.load_data(keep_orig=False,show_links=False)
Extracting data from Receita Federal do Brasil...
Data loaded successfully.
df
Loading...

Processamento adicional

  • Listagem de entidades disponíveis para análise

# lista de entidades disponíveis
df['Entidade'].unique()
array(['FNDE', 'INCRA', 'SENAI', 'SESI', 'SENAC', 'SESC', 'SEBRAE', 'EMBRATUR', 'DPC', 'ANAC', 'SENAR', 'SEST', 'SENAT', 'SESCOOP', 'SDR', 'APEX-BR', 'ABDI'], dtype=object)
  • Escolha de entidade e filtragem

entity = 'INCRA'
df_e = df[df['Entidade'] == entity].reset_index(drop=True)

Mapeamento

  • Criação de string representativa de temporalidade;

  • Conversão de string para objeto datetime;

  • Plotagem direta de curvas em eixos cartesianos;

    • Frequência mensal;

    • Frequência anual;

  • Montagem de string representativa da temporalidade (período)

df_e['Período'] = pd.Series([v['Mês'] + '/' + v['Ano'] for i,v in df_e.iterrows()])
df_e
Loading...
  • Plotagem simples

    • Eixo emaranhado;

    • Falta de controle de espaçamento;

fig, ax = plt.subplots(figsize=(12,3),constrained_layout=True)
s1 = sb.lineplot(data=df_e,x='Período',y='Total Repassado',
                 #errorbar=None,
                 ax=ax)
ax.tick_params(axis='x', rotation=90, labelsize = 8)
<Figure size 1200x300 with 1 Axes>
  • Transformação para objeto datetime

# ver função 'map_my' auxiliar
df_e['Período'] = pd.to_datetime(df_e['Período'].apply(lambda x: dcs27.map_my(x)))

Visualização

Iterando em RVs primárias

  • Plotagem com eixo automaticamente controlado

    • Exploração de seaborn.lineplot

  • Quadro de STs (frequência mensal)

fig, ax = plt.subplots(figsize=(12,3),constrained_layout=True)
s1 = sb.lineplot(data=df_e,
                 x='Período', y='Total Repassado',
                 color=plt.rcParams['axes.edgecolor'], # cor do estilo customizado
                 #errorbar=None, 
                 ax=ax)
ax.set_title(f'Série histórica: repasse RFB para {entity}',fontsize=14);
<Figure size 1200x300 with 1 Axes>
  • Plotagem de séries por frequência mensal

df_em = df_e.set_index('Ano')
df_em
Loading...
fig, ax = plt.subplots(figsize=(12,3),constrained_layout=True)

# paleta de cores
pal = sb.color_palette('Oranges',len(df_em.index.unique()))

# 
for i,y in enumerate(df_em.index.unique()):
#     sy = sb.lineplot(data=df_em,
#                      x=df_em.loc[y]['Mês'],
#                      y=df_em.loc[y]['Total Repassado'],
#                      marker='o',
#                      color=pal[i],
#                      #errorbar=None, 
#                      #ax=ax, 
#                      label=y)

        plt.plot(df_em.loc[y]['Mês'],df_em.loc[y]['Total Repassado'],'o-',color=pal[i],label=y)
    
    
ax.legend(loc='best', bbox_to_anchor=(1.1,1.1), title='Ano')
ax.grid(axis='x')
ax.set_title(f'Série histórica (mensal): repasse RFB para {entity}',fontsize=14);
<Figure size 1200x300 with 1 Axes>
  • Identificação de componentes

Nota 1: STs podem ou não apresentar padrões. Padrões comuns são: i) tendência (comportamento monotônico); ii) sazonalidade (comportamento alternado devido a fatores sazonais); iii) híbrido (comportamento que apresenta tendências e efeitos sazonais combinados).

Nota 2: uma ST pode ser descrita por uma soma ou um produto de componentes:

  • statsmodels.tsa.seasonal_decompose reproduz a ST observada e outras 3 componentes.

  • ST aditiva: valor = tendência + ciclo + sazonalidade + irregularidade

# componentes por modelo aditivo
df_add = seasonal_decompose(x=df_em.set_index('Período')['Total Repassado'], 
                            model='additive', 
                            extrapolate_trend='freq')

# figura
fig, ax = plt.subplots(4,1,figsize=(6,4),sharex=True,constrained_layout=True)

# plotagem das componentes
ax[0].plot(df_add.observed,color=pal[2])
ax[1].plot(df_add.trend,color=pal[4])
ax[2].plot(df_add.seasonal,color=pal[6])
ax[3].plot(df_add.resid,'o',color=pal[8])

# decoração
ax[0].set_title('Série temporal observada',fontsize=10)
ax[1].set_title('Componente: tendência',fontsize=10)
ax[2].set_title('Componente: sazonalidade',fontsize=10)
ax[3].set_title('Componente: irregularidade',fontsize=10)
ax[3].set_xlabel('Período',fontsize=10)
fig.suptitle('Componentes da ST: modelo aditivo');
<Figure size 600x400 with 4 Axes>
  • ST multiplicativa: valor = tendência x ciclo x sazonalidade x irregularidade

# componentes por modelo multiplicativo
df_mul = seasonal_decompose(x=df_em.set_index('Período')['Total Repassado'], 
                            model='multiplicative', 
                            extrapolate_trend='freq')

# figura
fig, ax = plt.subplots(4,1,figsize=(6,4),sharex=True,constrained_layout=True)

# plotagem das componentes
ax[0].plot(df_mul.observed,color=pal[2])
ax[1].plot(df_mul.trend,color=pal[4])
ax[2].plot(df_mul.seasonal,color=pal[6])
ax[3].plot(df_mul.resid,'o',color=pal[8])

# decoração
ax[0].set_title('Série temporal observada',fontsize=10)
ax[1].set_title('Componente: tendência',fontsize=10)
ax[2].set_title('Componente: sazonalidade',fontsize=10)
ax[3].set_title('Componente: irregularidade',fontsize=10)
ax[3].set_xlabel('Período',fontsize=10)
fig.suptitle('Componentes da ST: modelo multiplicativo');
<Figure size 600x400 with 4 Axes>
  • Mecanismo de plotagem direta

dp = df_add.plot()
<Figure size 640x480 with 4 Axes>

RV finalística

  • Define função para plotar ST(s) específica(s) com alguma decoração.

df['Entidade'].unique()
array(['FNDE', 'INCRA', 'SENAI', 'SESI', 'SENAC', 'SESC', 'SEBRAE', 'EMBRATUR', 'DPC', 'ANAC', 'SENAR', 'SEST', 'SENAT', 'SESCOOP', 'SDR', 'APEX-BR', 'ABDI'], dtype=object)
# entidades do sistema S
S = ['ABDI']

fig, ax = plt.subplots(figsize=(12,3),constrained_layout=True)

# plotagens individuais
for i,s in enumerate(S):
    s1 = dcs27.plot_ts_rfb(df,s,ax,pal[i+3]) # função auxiliar

ax.set_title(f'Série histórica: repasses anuais da RFB para entidades do Sistema S',fontsize=14);
<Figure size 1200x300 with 1 Axes>