Curso

Conseguir criar gráficos sofisticados e fáceis de entender é essencial para se tornar um(a) cientista de dados de sucesso. Visualizações são uma ótima forma de contar a história que está por trás dos seus dados. Elas destacam relações e revelam informações que o olho humano percebe e que não aparecem só com números. Mas sabe o que é ainda melhor do que visualizações estáticas para análise? Visualizações interativas!
Para quem está começando, isso pode parecer um desafio. Python e R oferecem uma grande variedade de ferramentas e truques para te ajudar nessa tarefa. Neste tutorial, vamos apresentar o Altair. Com o Altair, você cria visualizações significativas, elegantes e eficientes com poucas linhas de código e em pouquíssimo tempo. Vamos nessa?
O que é o Altair?
Altair é uma biblioteca Python criada para visualização estatística. Ela é declarativa por natureza (já já explicamos isso). Baseia-se no Vega e no Vega-Lite, que são gramáticas de visualização que permitem descrever a aparência visual e o comportamento interativo de um gráfico em formato JSON.
APIs imperativas vs. declarativas
Como dissemos, Python já tem ótimas ferramentas e bibliotecas para visualização de dados, muitas com suporte a interatividade. Então, o que faz o Altair se destacar?
A resposta está na sua natureza declarativa, em contraste com APIs imperativas.
Com APIs imperativas, você foca no "como fazer" em vez do "o que quer fazer". É preciso pensar no código para construir a visualização e especificar manualmente passos do plot — limites de eixos, tamanho, rotação, legendas etc.
Como cientista de dados, o Altair permite que você concentre tempo e esforço nos dados — entendendo, analisando e visualizando — em vez do código para chegar lá. Você define o dado e o resultado que espera ver (como a visualização deve ficar no fim), e o Altair faz as manipulações necessárias automaticamente.
Instalação
Neste tutorial, vamos usar um conjunto de dados de exemplo do Vega Datasets. Para instalar o Altair junto com o Vega Datasets, rode no console:
$ pip install altair vega_datasets
Se você usa o gerenciador de pacotes conda, o equivalente é:
$ conda install -c conda-forge altair vega_datasets
Depois disso, abra seu Jupyter Notebook e importe o Altair para começar. Para saber mais sobre Jupyter Notebook, confira o guia definitivo do Jupyter Notebook da DataCamp.
Dados
Agora que instalamos o Altair e o Vega Datasets, é hora de carregar alguns dados. Comece com os imports abaixo:
import pandas as pd
import altair as alt
Por que importar o pandas?
Como o Altair é construído em torno do DataFrame do pandas, você pode manipular dados no Altair do mesmo jeito que faria com um DataFrame do pandas.
E, embora internamente o Altair armazene dados como um DataFrame do pandas, há várias formas de fornecer os dados:
- como um DataFrame do pandas
- como um objeto Data ou relacionado (por exemplo, UrlData, InlineData, NamedData)
- como uma string de URL apontando para um arquivo de texto em JSON ou CSV
- como um objeto que suporte a geo_interface (por exemplo, Geopandas GeoDataFrame, Shapely Geometries, objetos GeoJSON)
Movies Dataset
Neste tutorial, vamos trabalhar com o Movies Dataset do Vega Datasets. Esse e outros datasets sobre filmes são famosos na comunidade de ciência de dados, especialmente em motores de recomendação. Aqui, porém, vamos apenas analisar dados com visualizações no Altair.
O conjunto traz informações como título do filme, bilheteria nos EUA e no mundo, orçamento de produção, gênero, e notas do IMDB e Rotten Tomatoes. Não usaremos todas as colunas; vamos focar em algumas para entender como o Altair funciona como ferramenta de visualização.
Vamos buscar o dataset e fazer uma análise simples para entendê-lo melhor.
# Importando o Vega Dataset
from vega_datasets import data as vega_data
movies_df = pd.read_json(vega_data.movies.url)
# Conferindo o tipo de dado carregado
print("movies_df is of the type: ", type(movies_df))
print("movies_df: ", movies_df.shape)
movies_df is of the type: <class 'pandas.core.frame.DataFrame'>
movies_df: (3201, 16)
Como você viu, movies_df é um DataFrame do pandas e tem 3201 filmes (linhas) com 16 atributos (colunas) cada. Vamos espiar os dados dentro do dataframe.
movies_df.head(5)
| Title | US_Gross | Worldwide_Gross | US_DVD_Sales | Production_Budget | Release_Date | MPAA_Rating | Running_Time_min | Distributor | Source | Major_Genre | Creative_Type | Director | Rotten_Tomatoes_Rating | IMDB_Rating | IMDB_Votes | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | The Land Girls | 146083.0 | 146083.0 | NaN | 8000000.0 | Jun 12 1998 | R | NaN | Gramercy | None | None | None | None | NaN | 6.1 | 1071.0 |
| 1 | First Love, Last Rites | 10876.0 | 10876.0 | NaN | 300000.0 | Aug 07 1998 | R | NaN | Strand | None | Drama | None | None | NaN | 6.9 | 207.0 |
| 2 | I Married a Strange Person | 203134.0 | 203134.0 | NaN | 250000.0 | Aug 28 1998 | None | NaN | Lionsgate | None | Comedy | None | None | NaN | 6.8 | 865.0 |
| 3 | Let's Talk About Sex | 373615.0 | 373615.0 | NaN | 300000.0 | Sep 11 1998 | None | NaN | Fine Line | None | Comedy | None | None | 13.0 | NaN | NaN |
| 4 | Slam | 1009819.0 | 1087521.0 | NaN | 1000000.0 | Oct 09 1998 | R | NaN | Trimark | Original Screenplay | Drama | Contemporary Fiction | None | 62.0 | 3.4 | 165.0 |
Os nomes das colunas são:
movies_df.columns
Index(['Title', 'US_Gross', 'Worldwide_Gross', 'US_DVD_Sales',
'Production_Budget', 'Release_Date', 'MPAA_Rating', 'Running_Time_min',
'Distributor', 'Source', 'Major_Genre', 'Creative_Type', 'Director',
'Rotten_Tomatoes_Rating', 'IMDB_Rating', 'IMDB_Votes'],
dtype='object')
Agora vamos usar a função to_datetime do pandas para converter a coluna Release_Date em uma data real e depois extrair o ano. Depois, vamos usar essa nova coluna nas visualizações.
def extract_year(value):
return pd.to_datetime(value, format='%b %d %Y').year
movies_df["Year"] = movies_df["Release_Date"].apply(extract_year)
Se você checar novamente as colunas, verá uma nova coluna chamada Year com o ano correspondente a cada filme.
movies_df.columns
Index(['Title', 'US_Gross', 'Worldwide_Gross', 'US_DVD_Sales',
'Production_Budget', 'Release_Date', 'MPAA_Rating', 'Running_Time_min',
'Distributor', 'Source', 'Major_Genre', 'Creative_Type', 'Director',
'Rotten_Tomatoes_Rating', 'IMDB_Rating', 'IMDB_Votes', 'Year'],
dtype='object')
Agora vamos criar alguns gráficos. Antes disso, rode este trecho:
alt.renderers.enable('notebook')
RendererRegistry.enable('notebook')
Esse código permite que o Altair renderize os gráficos inline no Jupyter Notebook, assim você vê as figuras conforme as cria. Se tiver problemas, confira a página de troubleshooting do Altair.
Num primeiro olhar, é interessante ver a relação entre quanto se gastou para fazer o filme (Production_Budget) e quanto ele rendeu (Worldwide_Gross). Vamos colocar esses valores nos eixos X e Y.
Como o dataset é relativamente grande — e nosso foco é brincar com o Altair — vamos trabalhar só com alguns pontos por enquanto. Vamos ver quantos filmes há em cada ano e escolher um para focar.
movies_df["Year"].value_counts()
2006 220
2005 210
2002 208
2004 192
2000 188
...
1943 1
2015 1
2027 1
2037 1
1928 1
Name: Year, Length: 91, dtype: int64
Vamos focar no ano 2000 e criar um novo dataframe movies_2000 contendo apenas dados desse ano. Ele deve ter 188 linhas (filmes).
movies_2000 = movies_df[movies_df["Year"] == 2000]
movies_2000.shape
(188, 17)
Agora vamos partir para a primeira visualização. Para isso, vamos entender um pouco melhor o formato do Altair.
Charts
Charts são objetos fundamentais no Altair e aceitam um único argumento: um dataframe. Definimos um chart assim:
alt.Chart(DataFrame)
Porém, sozinho ele não faz muita coisa além de dizer qual é o dado. Depois, você precisa informar o que quer fazer com esse dado. É aí que entram as marks.
Marks
A propriedade mark indica como os dados serão representados no gráfico. Veja abaixo as marks básicas do Altair:

No nosso caso, queremos marcar cada valor do DataFrame como um ponto (círculo) no gráfico. Portanto:
alt.Chart(DataFrame).mark_point()
Encodings
Depois de definir os dados e como serão representados, precisamos dizer onde representá-los: posições, tamanho, cor etc. É para isso que usamos encodings:
alt.Chart(DataFrame).mark_point().encode()
Juntando tudo e adicionando detalhes para criar nossa primeira visualização:
alt.Chart(movies_2000).mark_point().encode(
alt.X('Production_Budget'),
alt.Y('Worldwide_Gross')
)
<vega.vegalite.VegaLite at 0x11709a1d0>

Legal, né? Com pouca coisa — entendemos a terminologia e juntamos tudo. Agora temos um gráfico que mostra gasto vs. arrecadação mundial dos filmes do ano 2000 no nosso dataset.
Vamos deixar esse gráfico mais interessante. Em vez de todos os pontos terem o mesmo tamanho, vamos dimensioná-los pelo US_Gross. Para isso, usamos o recurso Size. Quanto maior o círculo, maior a bilheteria nos EUA. Vamos também preencher os círculos com cor, adicionando um argumento ao mark_point().
alt.Chart(movies_2000).mark_point(filled=True).encode(
alt.X('Production_Budget'),
alt.Y('Worldwide_Gross'),
alt.Size('US_Gross')
)
<vega.vegalite.VegaLite at 0x117cce790>

Agora temos um gráfico que mostra os orçamentos e destaca a bilheteria nos EUA em apenas quatro linhas. O que está faltando? Cor!
Mas não vamos colorir por colorir. Vamos aproveitar outra informação do dataset, Major_Genre. Cada gênero terá sua própria cor usando o recurso Color, e adicionaremos transparência com OpacityValue.
alt.Chart(movies_2000).mark_point(filled=True).encode(
alt.X('Production_Budget'),
alt.Y('Worldwide_Gross'),
alt.Size('US_Gross'),
alt.Color('Major_Genre'),
alt.OpacityValue(0.7)
)
<vega.vegalite.VegaLite at 0x118e3ff50>

Está bom, mas pode melhorar! Seria ótimo poder explorar o gráfico e ver detalhes do filme representado por cada ponto. O tooltip resolve isso para a gente…
alt.Chart(movies_2000).mark_point(filled=True).encode(
alt.X('Production_Budget'),
alt.Y('Worldwide_Gross'),
alt.Size('US_Gross'),
alt.Color('Major_Genre'),
alt.OpacityValue(0.7),
tooltip = [alt.Tooltip('Title'),
alt.Tooltip('Production_Budget'),
alt.Tooltip('Worldwide_Gross'),
alt.Tooltip('US_Gross')
]
)
<vega.vegalite.VegaLite at 0x118e3ff90>

Demais, né? Mas vamos além. Lembra por que escolhemos o Altair? Para criar visualizações interativas. O tooltip já traz alguma interação ao passar o mouse pelos pontos. Agora, vamos adicionar a funcionalidade interactive()…
alt.Chart(movies_2000).mark_point(filled=True).encode(
alt.X('Production_Budget'),
alt.Y('Worldwide_Gross'),
alt.Size('US_Gross'),
alt.Color('Major_Genre'),
alt.OpacityValue(0.7),
tooltip = [alt.Tooltip('Title'),
alt.Tooltip('Production_Budget'),
alt.Tooltip('Worldwide_Gross'),
alt.Tooltip('US_Gross')
]
).interactive()
<vega.vegalite.VegaLite at 0x118e3c750>

Com esse pequeno ajuste, você já pode dar zoom em áreas específicas — os eixos se ajustam automaticamente para facilitar o foco. Mas há recursos interativos bem mais avançados que podemos adicionar. Vamos ver um deles…
Já temos um gráfico bem legal para mostrar nossos dados. Vamos trazer todos os pontos para o gráfico. Mas, calma: pode ficar demais em uma única visualização. E queremos separar pelos valores de Year que criamos antes. Para isso, vamos usar uma propriedade avançada de selection.
select_year = alt.selection_single(
name='Select', fields=['Year'], init={'Year': 1928},
bind=alt.binding_range(min=1928, max=2046, step=10)
)
alt.Chart(movies_df).mark_point(filled=True).encode(
alt.X('Production_Budget'),
alt.Y('Worldwide_Gross'),
alt.Size('US_Gross'),
alt.Color('Major_Genre'),
alt.OpacityValue(0.7),
tooltip = [alt.Tooltip('Title:N'),
alt.Tooltip('Production_Budget:Q'),
alt.Tooltip('Worldwide_Gross:Q'),
alt.Tooltip('US_Gross:Q')
]
).add_selection(select_year).transform_filter(select_year)
<vega.vegalite.VegaLite at 0x117cd4cd0>

Usamos add_selection para incluir select_year como seleção única no gráfico e depois aplicamos transform_filter() para filtrar de fato.
Percebeu outra novidade no código? As letras "Q" e "N" no Tooltip. Elas especificam o tipo de dado: N-Nominal (categórico), Q-Quantitativo (numérico), O-Ordinal (ordenado) e T-Temporal (pontos ou intervalos de tempo).
Confira o ano mais antigo e o mais recente do dataset.
print("The oldest year is: ", movies_df["Year"].min())
print("The latest year is: ", movies_df["Year"].max())
The oldest year is: 1928
The latest year is: 2046
Ao arrastar a barra "Select_Year", dá para ver que quase não há filmes entre 1928 e 1967. E não há dados após 2018 — certamente não até 2046. Podemos usar binding_range() para ajustar o intervalo e o passo dos anos.
Em projetos reais, achados assim são importantes e podem apontar erros na coleta ou no processamento dos dados. É preciso tratá-los com cuidado — etapa essencial da preparação de dados. Veja o tutorial Data Preparation with pandas para uma introdução a esses passos vitais.
Vamos ajustar os anos e, com isso, temos nossa visualização final…
select_year = alt.selection_single(
name='Select', fields=['Year'], init={'Year': 1968},
bind=alt.binding_range(min=1968, max=2008, step=10)
)
alt.Chart(movies_df).mark_point(filled=True).encode(
alt.X('Production_Budget'),
alt.Y('Worldwide_Gross'),
alt.Size('US_Gross'),
alt.Color('Major_Genre'),
alt.OpacityValue(0.7),
tooltip = [alt.Tooltip('Title:N'),
alt.Tooltip('Production_Budget:Q'),
alt.Tooltip('Worldwide_Gross:Q'),
alt.Tooltip('US_Gross:Q')
]
).add_selection(select_year).transform_filter(select_year)
<vega.vegalite.VegaLite at 0x1180cda10>

Neste tutorial, você foi apresentado ao Altair. Viu como poucas linhas de código bastam para criar gráficos bonitos e interativos que ajudam a contar melhor a história dos seus dados. Esperamos ter mostrado o poder e o potencial do Altair. Para saber mais, visite o site oficial.

