Apresentar informações estatísticas por meio de gráficos pode ser uma ferramenta importante para melhorar o entendimento de informações complexas. Para isso, deve-se elaborar um gráfico eficiente. Uma forma é mais eficiente que a outra se sua informação pode ser decodificada pela maioria dos leitores de forma mais rápida ou mais fácil de acordo com Robbins (2004). Portanto, cuidados são necessários para que os gráficos não sejam ineficientes, confusos ou transmitam informações erradas.
Esta nota tem por objetivo apresentar o material utilizado e as rotinas realizadas para a apresentação de dados estatísticos econômicos com o pacote ggplot2. Esse pacote permite apresentar dados seguindo uma “gramática de gráficos”, que “makes ggplot2 very powerful because you are not limited to a set of pre-specified graphics, but you can create new graphics that are precisely tailored for your problem”, conforme Wickham (2015).
Em síntese, Wickham (2015) explica essa gramática de gráficos como uma representação estatística que mapeia informações em atributos estéticos (cores, formatos, tamanhos) de objetos geométricos (pontos, linhas, barras) em um sistema específico de coordenadas. Diferentes facetas podem ser usadas para representar, numa única imagem, diferentes subconjuntos de uma tabela. E é a combinação desses elementos que forma um gráfico.
Do ponto de vista mais concreto, em primeiro lugar, é necessário instalar (uma única vez) e carregar os pacotes abaixo para realizar as rotinas no R2.
# install.packages("tidyverse") Instala o pacote tidyverse, por exemplo
library(tidyverse) # Organização das tabelas e elaboração de gráficos
library(RColorBrewer) # Paletas de cores para os gráficos
library(viridis) # Paletas de cores para os gráficos
library(ggthemes) # Interfaces gráficas adicionais
library(scales) # Ajuste de escala dos gráficos
library(lubridate) # Ferramenta para ajuste de datas
library(zoo) # Ferramenta também para ajuste de datas
library(sidrar) # Acessar dados do IBGE
library(rbcb) # Acessar dados do BCB
options(scipen = 999)
Um bom processo de elaboração de gráficos exige que sua matéria prima esteja no formato ideal, com as tabelas devidamente organizadas. Esse processo de organização leva à chamada ``tidy data’’ (por isso o nome do primeiro pacote utilizado), conforme Wickham (2014). Em síntese, os dados devem ser organizados de duas formas. Cada valor (cada célula numa tabela do Excel, por exemplo) pertence a uma variável e a uma observação. Variável contém valores que se referem a uma mesma característica ou atributo — podemos citar como exemplos a data, o valor da taxa de inflação ou da taxa de desocupação e etc. — e são representadas por colunas. Cada observação, isto é, cada linha contém todos os valores medidos sobre uma mesma unidade, como uma região e um trimestre.
Todos os gráficos feitos com o ggplot2 têm seis componentes básicos:
Os três primeiros elementos são normalmente suficientes para análises exploratórias dos dados, em que o objetivo é conhecer melhor os dados que foram coletados. Tratam-se de gráficos usados apenas pelo pesquisador e, em geral, são insuficientes para apresentação dos resultados.
Para fins desta nota, utilizaremos em quase todos os gráficos as informações relativas à taxa de desocupação da força de trabalho (Tabela 6397), ao rendimento médio real (Tabela 5437) e à média de horas habitualmente trabalhadas por semana (Tabela 6372) por grupos de idade entre o 1o trimestre de 2016 e o 1o trimestre de 2020. Todas as informações foram coletadas na Pesquisa Nacional por Amostra de Domicílios Contínua Trimestral (PNADC/T), realizada pelo IBGE. Os dados são baixados por meio do pacote sidrar. Nesse caso, baixaremos as tabelas individualmente e, ao final, juntaremos pelas categorias em comum. As informações para identificar os elementos das tabelas que queremos podem ser acessadas pela função info_sidra().
## Tabela 6397 - Taxas de desocupação e de subutilização da força de trabalho,
## na semana de referência, das pessoas de 14 anos ou mais de idade,
## por grupos de idade
# info_sidra(6397,wb = T)
desocupacao <- get_sidra(6397,
period = "201601-202001", # Seleciona trimestres
geo = "Region", # 5 Regiões Brasileiras
variable = c(4099),
format = 2)
tabela1 <- desocupacao %>%
rename("Desocupacao" = Valor) %>% # Renomeia a variável de interesse
select(`Grande Região`,Trimestre, `Grupo de idade`,Desocupacao)
head(tabela1, n = 3) # Mostra as três primeiras linhas
## Tabela 5437 - Rendimento médio real, habitualmente recebido por mês e
## efetivamente recebido no mês de referência, do trabalho principal e
## de todos os trabalhos, por grupos de idade
# info_sidra(5437,wb = T)
rendimento <- get_sidra(5437,
period = "201601-202001",
geo = "Region",
variable = c(5932),
format = 2)
tabela2 <- rendimento %>%
rename("Rendimento" = Valor) %>%
select(`Grande Região`,Trimestre, `Grupo de idade`,Rendimento)
head(tabela2, n = 3)
## Tabela 6372 - Média de horas habitualmente trabalhadas por semana e
## efetivamente trabalhadas na semana de referência, no trabalho principal
## e em todos os trabalhos, das pessoas de 14 anos ou mais de idade,
## por grupos de idade
#info_sidra(6372,wb = T)
horas <- get_sidra(6372,
period = "201601-202001",
geo = c("Region"),
variable = c(8186),
format = 2)
tabela3 <- horas %>%
rename("Horas" = Valor) %>%
select(`Grande Região`,Trimestre, `Grupo de idade`,Horas)
head(tabela3, n = 3)
## Tabela com todos os dados agrupados por `Grande Região`,
## `Trimestre` e `Grupo de Idade`
emprego <- tabela1 %>%
left_join(tabela2) %>%
left_join(tabela3)
head(emprego, n = 2)
Portanto, trabalharemos com a tabela chamada ``emprego’’. Um gráfico simples que relaciona horas trabalhadas e rendimento é:
ggplot(emprego,
aes(x = Horas, y = Rendimento)) +
geom_point()
Note que o sinal de + é usado para adicionar camadas ao gráfico como padrão do pacote. Uma elaboração mais completa dos gráficos envolve, normalmente, os seis componentes básicos e serão detalhados abaixo.
Pode-se adicionar variáveis ao gráfico com a atribuição de cores (colour) e formato (shape) para variáveis categóricas e tamanho (size) para variáveis contínuas, que serão acompanhados de legenda:
ggplot(emprego,
aes(x = Horas, y = Rendimento, shape = `Grupo de idade`)) +
geom_point()
Se a intenção é dar uma cor fixa para um determinado valor, usa-se o argumento fora do padrão aes() e na geometria de interesse. Vale notar que as estéticas passadas para o termo ggplot() valem para todas as camadas. As informações passadas como estéticas dos geoms valem apenas para a geometria específica.
ggplot(emprego,
aes(x = Horas, y = Rendimento, shape = `Grupo de idade`)) +
geom_point(color = "red")
Podemos adicionar variáveis categóricas por meio de facetas, que dividem o gráfico em subconjuntos. A forma mais simples é de modo wrapped, com o nome da variável precedido de um ~:
ggplot(emprego,
aes(x = Horas, y = Rendimento, color = `Grupo de idade`)) +
geom_point(shape = 1)+ # Formato fixo de círculo
facet_wrap(~`Grande Região`)
O pacote também fornece algumas geometrias diferentes que podem ser adaptadas às características dos dados a serem apresentados. Elas representam o “tipo” de gráfico que se quer apresentar. Note que é possível usar mais de uma geometria.
Um primeiro exemplo sobre o uso múltiplo de geometrias consiste em adicionar uma linha de regressão linear com o respectivo intervalo de confiança para os dados:
ggplot(emprego,
aes(x = Horas, y = Rendimento)) +
geom_point(alpha = 0.4)+ # Transparência dos pontos
geom_smooth(method = "lm")
Histogramas e polígonos de frequência podem ser interessantes para mostrar a distribuição de uma única variável numérica. O temanho dos intervalos pode ser estabelecido com o argumento binwidth:
ggplot(emprego, aes(x = Rendimento)) +
geom_histogram(fill = "blue",binwidth = 200)
ggplot(emprego, aes(x = Rendimento)) +
geom_freqpoly(color = "red")
Variáveis categóricas são automaticamente dispostas em ordem alfabética, mas podem ser reorganizadas conforme alguma variável quantitativa de referência com a função reorder().
ggplot(emprego, aes(x = reorder(`Grupo de idade`, Desocupacao), y = Desocupacao)) +
geom_boxplot()
Os eixos podem ser customizados com alterações dos nomes (labels) e de seus tamanhos3 de modo a ficaram mais intuitivos e explicativos ao leitor.
ggplot(emprego,
aes(x = Horas, y = Rendimento)) +
geom_point()+
labs(x = "Horas de Trabalho",
y = "Renda habitual")
ggplot(emprego,
aes(x = `Grande Região`, y = Rendimento, colour = `Grupo de idade`)) +
geom_jitter(width = 0.3)+ # Acrescenta variações para reduzir sobreposições
labs(x = NULL,
y = NULL,
title = "Renda por Região (R$)",
colour = "Idade")+
ylim(c(700,3100)) # Limite ao eixo y
## Warning: Removed 73 rows containing missing values (geom_point).
O pacote também permite a visualização de mapas. A parte mais sensível é encontrar as coordenadas. Aqui, a apresentação será restrita a um mapa disponibilizado pelo pacote maps:
brasil <- map_data("world","brazil") %>%
select(lon = long, lat, group, id = subregion)
ggplot(brasil,aes(lon, lat)) +
geom_polygon(aes(group = group), fill = NA, colour = "black") +
coord_quickmap()
As escalas também podem ser alteradas para padrões distintos de cores.
ggplot(emprego, aes(x = Horas, y = Rendimento)) +
geom_point(aes(colour = `Grupo de idade`)) +
scale_y_log10() + # Escala do eixo y na base log_10
scale_colour_brewer(palette = "Set1") # Paleta de cores
Podemos também fazer uma mudança de coordenadas para melhorar a visualização ou adaptar nomes mais longos de variáveis:
ggplot(emprego,
aes(x = Horas, y = Rendimento)) +
geom_point()+
labs(x = "Horas de Trabalho",
y = "Renda habitual")
ggplot(emprego,
aes(x = Horas, y = Rendimento)) +
geom_point()+
labs(x = "Horas de Trabalho",
y = "Renda habitual")+
coord_flip()
Temas alteram as propriedades estéticas dos gráficos sem que sejam alteradas as formas como as informações são apresentadas em geometrias ou como os eixos são escalonados. Há alguns temas já prontos, tanto do pacote ggplot2, quanto de extensões como o ggthemes.
ggplot(emprego,
aes(x = Horas, y = Rendimento)) +
geom_point(alpha = 0.4)+
geom_smooth(method = "lm")+
theme_stata()
ggplot(emprego, aes(x = Rendimento)) +
geom_freqpoly(color = "red")+
theme_excel()
Para séries de tempo, é interessante o uso de gráficos de linha, que ligam os pontos da esquerda para a direita, ou gráfico de trajeto, que liga os pontos conforme a ordem que aparecem na tabela. A forma como o SIDRA disponibiliza as tabelas oferece datas em formato de caracteres, o que prejudica a representação contínua em um dos eixos. Para isso, precisaremos transformar a informação para formato de data. Como os dados são trimestrais, faremos a transformação usando os pacotes tidyverse e zoo.
emprego_data <- emprego %>%
mutate(Trimestre = str_replace(Trimestre,"º trimestre ","-"),
Trimestre = as.yearqtr(Trimestre, format = "%q-%Y"))
head(emprego_data, n = 3)
Além disso, queremos apenas os dados de desocupados agregados para o Brasil em ordem cronológica. Isso pode ser feito por:
emprego_data %>%
filter(`Grupo de idade` == "Total") %>% # Seleciona Total
ggplot(aes(Trimestre, Desocupacao, color = `Grande Região`)) +
geom_line(size = 1.25)
Podemos também fazer a representação de séries de tempo em que estamos interessados em um trajeto. Como exemplo, uma representação da Curva de Phillips para o Brasil, utilizando dados do núcleo do IPCA acumulado em 12 meses, fornecido pelo Banco Central.
#info_sidra(6381,wb = T)
desemprego <- get_sidra(6381,
period = "201201-202010",
variable = c(4099),
format = 2)
desemprego <- desemprego %>%
select(`Trimestre Móvel`, Valor) %>%
rename("Mês" = `Trimestre Móvel`,
"desemprego" = Valor) %>%
mutate(Mês = str_remove(Mês,".+-.+-"),
Mês = parse_date(str_c("01 ",Mês),
format = "%d %b %Y",
locale = locale("pt")))
# Núcleo da Inflação (Disponibilizado pelo Banco Central)
nucleo <- get_series(c("Valor" = 4466),
start_date = "2011-03-01",
end_date = "2020-10-01") %>%
mutate("indice" = 100,
"acumulado" = 0)
# Números índice
for (i in 1:(length(nucleo$Valor)-1)) {
nucleo[i+1,"indice"] <- (nucleo[i+1,"Valor"]/100+1)*nucleo[i,"indice"]
}
# Acumulado 12 meses
for (i in 13:length(nucleo$Valor)) {
nucleo[i,"acumulado"] <- (nucleo[i,"indice"]/nucleo[i-12,"indice"]-1)*100
}
# Junção das informações
curva_phillips <-
nucleo %>%
filter(date > "2012-02-01") %>%
left_join(desemprego, by = c("date" = "Mês"))
head(curva_phillips, n = 3)
ggplot(curva_phillips,aes(x = desemprego,y = acumulado,color = year(date)))+
geom_point()+
geom_path()
Pode-se, ainda mais, acrescentar títulos, alterar nomes dos eixos e de exibição da legenda além de acrescentar uma nota (caption) diretamente ao gráfico, todas de maneira customizada e/ou utilizando temas já prontos.
ggplot(curva_phillips,aes(x = desemprego,y = acumulado,color = year(date)))+
geom_point()+
geom_path()+
labs(title = "Curva de Phillips Brasil de mar/2012 a out/2020",
color = "Período",
x = "Taxa de Desocupação",
y = "Núcleo\n IPCA",
caption = "Taxa de desocupação PNADC-IBGE (tabela 6381) e
núcleo de inflação IPCA do BCB (série 4466)")+
theme_bw()+
theme(plot.title = element_text(face = "bold", size = 12),
axis.title.y = element_text(angle = 0, vjust = .5, hjust = 0))
Em termos gerais, os gráficos apresentados atende boa parte das demandas de representação visual de informações econômicas, ainda que de maneira resumida. Para uma apresentação completa de toda a versatilidade do pacote ggplot2, sugerimos a leitura de Wickham (2015).
Copyleft – Reprodução permitida desde que citada a fonte.
Robbins, Naomi B. 2004. Creating More Effective Graphs. New Jersey - USA: Wiley-Interscience. http://library1.nida.ac.th/termpaper6/sd/2554/19755.pdf.
Wickham, Hadley. 2014. “Tidy Data.” Journal of Statistical Software 59 (10): 1–23. http://www.jstatsoft.org/.
———. 2015. Elegant Graphics for Data Analysis. http://had.co.nz/ggplot2/book.
Doutorando em Economia pela Universidade de Brasília. Erros ou dúvidas podem ser enviadas para rafaeldeacyprestemr@gmail.com.↩
Ainda que nem todos sejam utilizados nesta nota, sugereimos ao leitor a consulta de informações adicionais dos pacotes para conhecer melhor suas respectivas funcionalidades.↩
A opção apresentada exclui as informações fora do intervalo. Para apenas aplicar um zoom sem que dados sejam eliminados, deve-se usar a opção coord_cartesian().↩