import pandas as pd
import altair as alt
Vega-Altair: Uma Breve Introdução
Vega-lite e Altair
Altair é uma biblioteca de gráficos estatísticos interativos para Python, que permite construir visualizações sofisticadas de maneira concisa. Existem outras bibliotecas para criação de gráficos interativos, como Bokeh e Plotly, porém Altair faz uso de uma linguagem declarativa para a construção dos gráficos, em oposição à linguagem imperativa utilizada por outras bibliotecas.
Em uma linguagem declarativa, o usuário fornece o que ele quer que a visualização inclua, em termos de dados, marcas gráficas e canais de codificação, ao invés de ter de especificar – através de código – como a visualização deve ser construída, o que muitas vezes envolve for-loops e outros comandos específicos, tornando o processo de exploração dos dados mais complicado, trabalhoso e pouco intuitivo.
Altair foi desenvolvida baseada em Vega-Lite, que é uma gramática de alto-nível para gráficos interativos. De uma maneira simplificada, os gráficos gerados são exibidos diretamente no navegador (Google Chrome, Safari, etc), então recomenda-se o uso de ambientes como JupyterLab, Kaggle or Colab.
A ideia chave é a de que o usuário deve declarar os links entre os dados que serão utilizados e os repectivos canais de codificação para os quais cada variável será direcionada. Esses termos ficarão mais claros nos exemplos que iremos trabalhar.
Bibliotecas
Vamos importar as bibliotecas necessárias: pandas para a leitura e manipulação dos dados, e altair para a visualização.
= 'O coração de Minas'
A = 'A cidade dos Profetas'
B = 'A mais charmosa de Minas'
C
= pd.DataFrame({
dados 'cidade': ['Ouro Preto', 'Ouro Preto', 'Ouro Preto', 'Congonhas', 'Congonhas', 'Congonhas', 'Tiradentes', 'Tiradentes', 'Tiradentes'],
'descricao': [A, A, A, B, B, B, C, C, C],
'mes': ['Jan', 'Mai', 'Set', 'Jan', 'Mai', 'Set', 'Jan', 'Mai', 'Set'],
'temperatura': [24.5, 18.7, 21.3, 27.2, 16.4, 23.8, 32.5, 9.7, 26.3],
})
# exibir o conteúdo de dados dados
cidade | descricao | mes | temperatura | |
---|---|---|---|---|
0 | Ouro Preto | O coração de Minas | Jan | 24.5 |
1 | Ouro Preto | O coração de Minas | Mai | 18.7 |
2 | Ouro Preto | O coração de Minas | Set | 21.3 |
3 | Congonhas | A cidade dos Profetas | Jan | 27.2 |
4 | Congonhas | A cidade dos Profetas | Mai | 16.4 |
5 | Congonhas | A cidade dos Profetas | Set | 23.8 |
6 | Tiradentes | A mais charmosa de Minas | Jan | 32.5 |
7 | Tiradentes | A mais charmosa de Minas | Mai | 9.7 |
8 | Tiradentes | A mais charmosa de Minas | Set | 26.3 |
Utilizamos o método DataFrame
da biblioteca pandas para criar uma tabela com 9 observações (linhas: 0 – 8) e quatro variáveis (colunas: cidade, descricao, mes e temperatura), e salvamos essa tabela em dados. Os números são fictícios, e não vamos nos preocupar com unidades de medida por enquanto.
O objeto Chart
O objeto fundamental em Altair é o Chart
, e ele recebe como argumento os dados que serão utilizados.
= alt.Chart(dados) grafico
Nessa linha de código, nós definimos o objeto Chart
e passamos para ele a tabela de dados que foi gerada anteriormente, mas não especificamos nada em relação ao que deve ser feito com esses dados.
Marcas Gráficas
Podemos agora especificar como gostaríamos de criar a visualização. O primeiro passo é definir a marca gráfica (tipo de gráfico) que queremos utilizar para representar os dados. Existem diversas possibilidades, mas vamos começar definindo a marca ponto, e para isso vamos utilizar o método mark_point
.
alt.Chart(dados).mark_point()
Perceba que obtivemos exatamente o especificado, as 9 observações contidas em dados foram plotadas uma em cima da outra parecendo que temos apenas um ponto, porém os 9 pontos estão no mesmo lugar. Isso aconteceu porque nenhum canal de codificação foi especificado, ou seja, não especificamos qual variável deve ser codificada no eixo-x, qual deve ser no eixo-y, qual deve codificada pela cor, etc.
Canais de Codificação
Para especificar os diferentes canais de codificação, iremos utilizar o método encode
.
alt.Chart(dados).mark_point().encode(= 'cidade' # a variável cidade codificada no eixo-y
y )
No gráfico acima, as observações (linhas da tabela) foram distribuídas ao longo do eixo-y, que codificou a variável cidade. Agora os pontos foram distribuídos, mas ainda estão parcialmente sobrepostos pois temos 9 observações, mas estamos exibindo apenas 3 pontos.
Iremos explorar aplicações de diferentes canais de codificação com algunas exemplos, veja uma breve lista com algumas das possibilidades:
y
: codificação do eixo-yx
: codificação do eixo-xcolor
: codificação das coresshape
: codificação dos formatossize
: codificação dos tamanhostooltip
: codificação para a interatividade
Vamos visualizar melhor as observações, codificando a variável temperatura no eixo-x:
alt.Chart(dados).mark_point().encode(= 'cidade',
y = 'temperatura'
x )
Agora temos uma visualização mais adequada e podemos perceber que, entre as três cidades, Tiradentes exibe a menor e a maior temperatura! Perceba agora a vantagem de Altair como uma linguagem declarativa: vamos criar variações alterando apenas as especificações dos canais de codificação.
alt.Chart(dados).mark_point().encode(= 'mes',
y = 'temperatura',
x = 'cidade' # a variável cidade codificada na cor
color )
alt.Chart(dados).mark_point().encode(= 'mes',
y = 'temperatura',
x = 'cidade' # a variável cidade codificada no formato
shape )
alt.Chart(dados).mark_point().encode(= 'mes',
y = 'temperatura',
x = 'cidade',
color = 'temperatura' # a variável temperatura codificada no tamanho
size )
Neste último gráfico, a variável temperatura está codificada tanto no eixo-x quanto no tamanho, e as legendas são geradas de maneira automática, porém você pode ajustá-las como preferir. Não me parece a melhor escolha de codificações para essa caso, mas ajuda a ilustrar as possibilidades.
Interatividade
Vamos agora codificar uma lista de duas variáveis no canal tooltip
, e criar interatividade através do método interactive
.
alt.Chart(dados).mark_point().encode(= 'mes',
y = 'temperatura',
x = 'cidade',
color = ['cidade', 'descricao'] # lista de duas variáveis codificadas para interatividade
tooltip ).interactive()
Perceba que as duas variáveis codificadas em tooltip
surgem quando o cursor é posicionado sobre cada ponto do gráfico. A interatividade também permite que o usuário aplique zoom ou movimente o interior do gráfico. Vale repetir, a linguagem declarativa permite a sobreposição de diversas funcionalidades com pouquíssimas linhas de código.
O exemplo que criamos pode ser muito simples, e não transmitir de maneira apropriada a capacidade e a elegância dessa biblioteca, mas você certamente irá apreciar a facilidade na criação de visualizações extremamente sofisticadas, incluindo datasets com dezenas de variáveis e milhares de observações.
Dados Agregados
Outra funcionalidade de Altair e sua linguagem declarativa é a de agregar os dados dentro da especificação da visualização, ou seja, elimina a necessidade de se utilizar pandas e agregar-los antes de cada visualização. Isso proporciona mais velocidade e mais espaço para explorar e experimentar, o que é extremamente importante.
No exemplo abaixo, nós iremos agregar os dados calculando a média da temperatura dentro do canal de codificação, isto é, iremos codificar a média das temperaturas no eixo-x:
alt.Chart(dados).mark_point().encode(='mean(temperatura)',
x='cidade'
y )
Ouro Preto apresenta a menor temperarura média. Podemos explorar agora outros tipos de gráfico para essa aplicação, o que equivale dizer outras marcas gráficas.
Alterando o Tipo de Marca
Vamos alterar o tipo de marca que utilizamos até agora para visualizar os dados para barras retangulares, para isso iremos substituir mark_point
por mark_bar
:
alt.Chart(dados).mark_bar().encode(='mean(temperatura)',
x='cidade'
y )
Digamos que você queira visualizar as barras na posição vertical. Perceba que nós não especificamos que as barras deveriam ser horizontais, como seria o caso para uma linguagem imperativa. Para alterar a orientação das barras, nós devemos apenas alterar as especificações dos canais de codificação, o que iremos fazer em seguida – e iremos também incluir a descrição da cidade quando o cursor estiver sobre as baras.
alt.Chart(dados).mark_bar().encode(='mean(temperatura)',
y='cidade', # cidade está agora codificada no eixo-x
x= 'descricao' # descrição codificada em tooltip
tooltip )
Vega-lite foi desenvolvida pelo Laboratório de Visualizações Interativas da Universidade de Washington. As propriedades dos gráficos, como dimensões, escalas, legendas, esquema de cores e etc são baseadas em décadas de pesquisa e são implementadas seguindo as melhores e mais atualizadas práticas.
Seguem os links para alguns videos que ilustram as motivações para a criação de Vega-lite por Jeffrey Heer e equipe, bem como as motivações para criação de Altair, por Jake VanderPlas e Brian Granger.