Explorando a visualização de dados com a biblioteca Altair
- Hermann Vargens
- 14 de mai. de 2022
- 4 min de leitura
Atualizado: 1 de set. de 2022

Este tutorial tem como objetivo ajudá-lo a usar a biblioteca Altair para criar visualizações de dados. Altair é uma biblioteca de visualização estatística declarativa para Python, baseada em Vega e Vega-Lite. Seu diferencial reside na possibilidade de visualisar rapidamente um conjunto de dados e fazer análises estatísticas, além de poder manipular a visualização de gráficos facilmente.
Instalação
Sua instalação é simples, semelhante à instalação de outras bibliotecas:
$ pip install altair vega_datasets
Ou se estiver usando um gerenciador de pacotes conda:
$ conda install -c conda-forge altair vega_dataset
Dados
Vamos explorar o dataset “Análise dos Filmes Exibidos 2009 a 2019”, obtido do Kaggle no link “https://www.kaggle.com/datasets/pedrothiago/anlise-dos-filmes-exibidos-2009-a-2019”. Trata-se de um conjunto de dados onde cada linha representa um filme, cada coluna contém os atributos do filme .
import pandas as pd
import numpy as np
df = pd.read_csv('.../Listagem_dos_Filmes_Brasileiros_e_Estrangeiros_Exibidos_2009_a_2019.csv')
Se tentarmos tentar trabalhar o Altair neste dataset, da forma como está, obteremos a seguinte mensagem de erro:
“The number of rows in your dataset is greater than the maximum allowed (5000). For information on how to plot larger datasets in Altair, see the documentation”
Como o objetivo do tutorial é fazer uma introdução ao Altair, vamos utilizar o método .sample() para selecionar aleatoriamente 5000 linhas:
df = df.sample(5000)
Em seguida, vamos deletar a primeira coluna e renomear as demais:
colunas = ['Ano', 'Titulo', 'Genero', 'Pais', 'Nacionalidade', 'Distribuidora', 'Pais_Distribuidora', 'Publico', 'Renda']
df.drop(columns='Unnamed: 0',inplace=True)
df.columns = colunas
Após verificar que não há valores ausentes, vamos visualizar nosso dataframe.
df.head()

Pronto! Agora que está tudo certo com nosso dataset, podemos dar prosseguimento.
O objeto “Chart”
Para usar a biblioteca Altair, primeiroprimeiro precisamos instanciar um objeto que receberá um dataframe como argumento, no nosso exemplo, será o objeto ‘chart’. É ele quem receberá os métodos e atributos necessários para gerar as visualizações.
chart = alt.Chart(df)
Encodings e Marks
Uma vez definido o objeto Chart, podemos especificar como gostaríamos que os dados fossem visualizados. Para isso, usamos o atributo ‘mark’, acesado através dos métodos “Chart.mark_*” (A * indica qual tipo de gráfico será gerado). Por exemplo:
chart.mark_point()

Apesar de estranha, a visualização acima contém todos os pontos do dataset, sobrepostos, pois não especificamos suas respectivas posições.
chart.mark_point().encode(alt.X('Genero'))

Para visualizar melhor os dados, precisamos separar visualmente os pontos, através do mapeamento de canais (encoding channels, ou simplesmente channels). Por exemplo, poderíamos codificar a variável “Genero” do dataframe, com o canal “x”.
Podemos prosseguir, e adicionar mais um canal, “y” para outra variável, por exemplo “Nacionalidade”:
chart.mark_point().encode(alt.X('Genero'),
alt.Y('Nacionalidade'))

É intuitivo que o gráfico acima representa que, para cada gênero de filme, temos os valores Brasileira e Estrangeira.
Gráficos de Dispersão (Scatter Plots)
Vamos utilizar duas variáveis numéricas (Renda e Público) disponíveis no dataset para verificar como os pontos se distribuem:
chart.mark_point().encode(alt.X('Publico'),
alt.Y('Renda'))

Também é possível modificar o tamanho dos pontos de acordo com uma determinada coluna.
chart.mark_point(filled=True).encode( alt.X('Publico'),
alt.Y('Renda'),
alt.Size('Renda'))

Podemos também usar cores, tornando as legendas mais interessantes. Para isso, usamos os parâmetros alt.Color(), tendo como argumento a coluna desejada. Também alteramos quão opacos podem ser os pontos, para facilitar a visualização.
chart.mark_point(filled=True).encode(alt.X('Publico'),
alt.Y('Renda'),
alt.Size('Renda'),
alt.Color('Genero'),
alt.OpacityValue(0.7))

O Altair permite tornar os gráficos mais interativos de forma fácil e prática. Por exemplo, se quisermos obter informações de cada ponto no gráfico, usamos o parâmetro alt.Tooltip[ ], cujo argumento são uma lista das features que queremos mostrar. Como nosso gráfico contém muitos pontos sobrepostos, vamos ainda empregar o parâmetro interactive(), que permite usar o mouse para dar zoom e deslocar o gráfico, conforme nosso interesse.
chart.mark_point(filled=True).encode(alt.X('Publico'),
alt.Y('Renda'),
alt.Size('Renda'),
alt.Color('Genero'),
alt.OpacityValue(0.7),
tooltip = [alt.Tooltip('Titulo'),
alt.Tooltip('Publico'),
alt.Tooltip('Renda')
]).interactive()

Acredito que nossa visualização melhorou bastante! Vamos acrescentar um último ingrediente, que o Altair é capaz de tornar ainda mais fácil: um filtro. Vamos permitir que seja possível filtrar as visualizações de acordo com o ano analisado. Para isso, vamos primeiramente definir um objeto que permitirá selecionar o ano:
select_year = alt.selection_single(name='Selecionar', fields=['Ano'], init={'Ano': 2009}, bind=alt.binding_range(min=2009, max=2019, step=1))
Os argumentos do método ‘selection_single()’ possuem um entendimento intuitivo. Primeiramente ‘name’ para criar o nome do botão de arrastar; ‘fields’ para a feature que será o nosso filtro e ‘init’ para dizer qual o primeiro valor (ano) a ser mostrado. O método ‘binding_range’ define os valores mínimos e máximos, e de quantos em quantos anos o filtro deverá agir (step).
Ao final do nosso código, colocamos o método add_selection(select_year) para adicionar a seleção e também o método transform_filter(select_year), cujo argumento também é o objeto ‘select_year’.
chart.mark_point(filled=True).encode(alt.X('Publico'),
alt.Y('Renda'),
alt.Size('Renda'),
alt.Color('Genero'),
alt.OpacityValue(0.7),
tooltip = [alt.Tooltip('Titulo'),
alt.Tooltip('Publico'),alt.Tooltip('Renda')]
).interactive().add_selection(select_year
).transform_filter(select_year)

Mais customizações de gráficos
Se você precisa customizar ainda mais o gráfico, é possível alterar legendas, eixos, cores, fontes, títulos, área do gráfico e muitos outros itens. Vou deixar aqui algumas sugestões mais usuais. Outras podem ser acessadas em https://altair-viz.github.io/user_guide/configuration.html#.
Configuração do tamanho do gráfico e adição de título
Para mudar o tamanho do gráfico, usamos o método .properties( width=200, height=150), onde width é a largura e height é a altura (os números 200 e 150 são apenas sugestões). Para adicionar um título, também devemos incluílo como argumento do método.
Configuração do título
Utiliza-se o método .configure_title(). logo após o parêntese que fecha o .encode().
Configuração dos eixos
Para configurar os eixos Y e X, basta usar os métodos .configure_axisY(), .configure_axisX() logo após o parêntese que fecha o .encode().
Pode-se também modificar a escala dos eixos.
Configuração dos ticks
Para cada tipo de tick, há um método para seleção. Por exemplo, para configurar barras, devemos usar o .configure_bar().
chart.mark_bar().encode(alt.Y('sum(Renda)',
title='Renda da Bilheteria (R$)',
scale = alt.Scale(domain=(0, 2500000000),clamp=True)), alt.X('Ano:N')).properties(title='Renda total dos filmes para o período de 2009-2019', width=400, height=300).configure_title( fontSize=25, font='Times', anchor='middle', color='black').configure_axisX( titleColor='blue', titleFontSize=14, labelColor='red', labelFontSize=14, labelAngle = 45).configure_axisY( titleColor='blue', titleFontSize=14, labelColor='red', labelFontSize=14).configure_bar( color='green', opacity = 0.5 )

Outros tipos de gráfico
Tipos diferentes de gráficos podem ser produzidos apenas modificando o método “mark”.
Descrição do método
Método | Descrição |
mark_arc() | Um gráfico de pizza. |
mark_area() | Um gráfico de área preenchida. |
mark_bar() | Um gráfico de barras. |
mark_circle() | Um gráfico de dispersão com círculos preenchidos. |
mark_geoshape() | Uma forma geográfica |
mark_image() | Um gráfico de dispersão com marcadores de imagem. |
mark_line() | Um gráfico de linha. |
mark_point() | Um gráfico de dispersão com formas de pontos configuráveis. |
mark_rect() | Um retângulo preenchido, usado para mapas de calor |
mark_rule() | Uma linha vertical ou horizontal que abrange o eixo |
mark_square() | Um gráfico de dispersão com quadrados preenchidos. |
mark_text() | Um gráfico de dispersão com pontos representados por texto. |
mark_tick() | Uma marca de escala vertical ou horizontal. |
mark_trail() | Uma linha com larguras variáveis. |
Box-plot
Examinamos a quantidade de filmes exibidos no Brasil no período de 2009 a 2019. Quando definimos ‘zero=False’, estamos modificando a escala para que seja exibido gráfico mais próximo do boxplot.
alt.Chart(source).mark_boxplot().encode( alt.Y('Quantidade',
title=None, scale=alt.Scale(zero=False))
).properties(title='Boxplot da quantidade de filmes produzidos no período de 2009-2019', width=500, height=300
).configure_axis(labelFontSize=16,titleFontSize=16
).configure_title(fontSize=22,font='Times',anchor='middle',color='black')

Pizza
O gráfico de pizza só chegou ao Altair recentemente. Para construí-lo, precisamos trabalhar um pouco o DataFrame.
source = pd.DataFrame(df['Genero'].value_counts().reset_index()).rename(columns={'index':'Genero','Genero':'Quantidade'})
base = alt.Chart(source).mark_arc().encode( theta=alt.Theta(field="Quantidade", type="quantitative"), color=alt.Color(field="Genero", type="nominal") )
pie = base.mark_arc(outerRadius=100) text = base.mark_text(radius=140, size=14).encode(text="Genero:N")
pie + text


Histograma
Vamos plotar um histograma básico. Aqui, usamos o ‘count’, que faz parte da própria sintaxe do Altair e dispensa que façamos um tratamento dos dados, para isso, poupando muito tempo.
alt.Chart(df).mark_bar().encode( alt.X("Genero"), alt.Y('count(Genero)')).properties( width=300, height=200).configure_mark( opacity=0.7, color='blue' )

Linhas
Na visualização abaixo, fizemos um gráfico de linhas e utilizamos o recurso ‘sum’, que assim como o ‘count’, faz parte da própria sintaxe do Altair.
chart.mark_line().encode( alt.X('Ano'), alt.Y('sum(Publico):Q'), )

Conclusão
Além do que foi apresentado aqui, abiblioteca Altair possui ainda diversos outros recursos que pretendo abordar futuramente, como a transformação de dados e filtros (utilizamos o transform_filter neste tutorial), que são muito interessantes e práticas, nos ajudando a economizar tempo e fazer análises mais objetivas.
Comments