No nosso primeiro tutorial de visualização de dados com Bokeh, você aprendeu a criar visualizações do zero usando glyphs. Agora, vamos ampliar esse conceito e construir gráficos a partir de diferentes estruturas de dados, como arrays e dataframes. Neste tutorial, você vai aprender a plotar dados com arrays do NumPy, dataframes no Pandas e ColumnDataSource usando Bokeh. O ColumnDataSource é a essência do Bokeh, pois permite compartilhar dados entre vários gráficos e widgets.
Gráficos do Bokeh a partir de arrays NumPy
Criando gráficos de linha com arrays NumPy
# Import packages
import numpy as np
import random
from bokeh.io import output_file, show
from bokeh.plotting import figure
# Create an array
x_array = np.array([10,20,30,40,50,60])
y_array = np.array([50,60,70,80,90,100])
# Create a line plot
plot = figure()
plot.line(x_array, y_array)
# Output plot
show(plot)

Criando gráficos de dispersão com arrays NumPy
# Import packages
import numpy as np
import random
from bokeh.io import output_file, show
from bokeh.plotting import figure
# Create arrays
x_arr = np.array([10,11,12,13,14,15,16])
y_arr = np.array([17,18,19,20,21,22,23])
# Create plot
plot = figure(title = "Scatter plot", x_axis_label = "Label name of x axis", y_axis_label ="Label name of y axis")
plot.circle(x_arr,y_arr, size = 30, alpha = 0.5)
# show plot
show(plot)
Isso gera o seguinte gráfico:

Criando gráficos usando dataframes do Pandas
Plotando linhas com dataframes do Pandas
Os dados deste exemplo vêm do Kaggle. O conjunto de dados contém todas as ações presentes no índice S&P 500 ao longo de cinco anos, até dezembro de 2018. O arquivo tem sete colunas:
- Date - data no formato aa-mm-dd
- Open - preço de abertura da ação
- High - maior preço do dia
- Low - menor preço do dia
- Close - preço de fechamento do dia
- Volume - volume negociado no dia
- Name - ticker da ação
Queremos ver a tendência das ações do Google ao longo dos cinco anos. Primeiro, carregamos os dados com o Pandas e conferimos as cinco primeiras linhas do dataframe.
# Import packages
import pandas as pd
# Load data
df = pd.read_csv('all_stocks_5yr.csv')
df.head()

# Focus on Google's stock
df_goog = df[df['Name'] == 'GOOG']
# Convert date column to a time series
df_goog['date'] = pd.to_datetime(df_goog['date'])
plot = figure(title= "Pandas Line Plot", x_axis_type = 'datetime', x_axis_label = 'date', y_axis_label= 'Prices')
plot.line(x = df_goog['date'], y = df_goog['high'])
# Output plot
show(plot)

No gráfico, foi necessário converter a coluna de datas para datetime para exibir corretamente no eixo x. Além disso, a função line (glyph no Bokeh) foi usada para gerar uma série temporal com os preços máximos do Google.
Criando um gráfico de dispersão a partir de um dataframe do Pandas
Nesta seção, usamos os dados abertos do S&P 500 disponíveis no Kaggle. Neste exemplo, queremos ver a correlação entre os preços das ações do Google e da Apple. Você pode saber mais sobre correlação neste link.
# Import required packages
# Import packages
import pandas as pd
from bokeh.io import output_file, show
from bokeh.plotting import figure
# Load data
df = pd.read_csv('all_stocks_5yr.csv')
# Select Google and Apple stock
df_goog = df[df['Name'] == 'GOOG']
df_apple = df[df['Name'] == 'AAPL']
# Select only 'date' and 'high' columns for Google and Apple
df_goog = df_goog[['date','high']]
df_apple = df_apple[['date','high']]
# Rename 'high' column to 'high_goog' and 'high_apple'
df_goog.rename(columns={'high': 'high_goog'}, inplace=True)
df_apple.rename(columns={'high': 'high_apple'}, inplace=True)
df_merged = pd.merge(df_goog, df_apple, how='inner', on='date')
# See the first five rows
df_merged.head(5)

O merge garante que os preços diários correspondam pela data. Isso evita o problema de correlacionar preços de dias diferentes, o que levaria a inferências estatísticas equivocadas.
# Create scatter plot
plot = figure(title= "Pandas Scatter Plot", x_axis_label = "Apple high prices", y_axis_label= "Google high prices")
plot.circle(x = df_merged['high_apple'], y = df_merged['high_goog'],color = 'red', size = 10, alpha = 0.8)
# Output the plot
show(plot)

Os círculos representam a relação entre os preços máximos da Apple e do Google. Observa-se uma correlação positiva geral entre os preços das duas ações.
Criando gráficos no Bokeh com ColumnDataSource
O objetivo do ColumnDataSource é permitir que você crie diferentes gráficos usando o mesmo conjunto de dados. Em resumo, ele funciona como uma base de dados para ser reutilizada em múltiplos gráficos e análises. Isso economiza tempo, pois você não precisa carregar os dados várias vezes no Jupyter Notebook.
O ColumnDataSource é semelhante a um dicionário do Python: os valores das colunas são acessados por chaves do tipo string com o nome de cada coluna.
Criando gráficos de linha usando ColumnDataSource
# Import packages
from bokeh.io import output_file, show
from bokeh.plotting import figure, ColumnDataSource
# Create the ColumnDataSource object
df_goog['date'] = pd.to_datetime(df_goog['date'])
data = ColumnDataSource(df_goog)
# Create time series plot
plot = figure(x_axis_type='datetime',
title='GOOG high prices ts plot',
x_axis_label = "Date",
y_axis_label = "Prices in $")
plot.line(x='date', y = 'high_goog', source = data, color = 'green')
show(plot)

O gráfico mostra como os preços máximos do Google evoluíram ao longo de 5 anos, com a linha indicando cada ponto de preço da ação.
Para criar esse gráfico, passamos todo o dataframe das ações do Google para a função ColumnDataSource e o salvamos na variável data.
Depois, usamos o argumento source para enviar esses dados à função de plotagem. Assim, podemos usar diretamente os nomes das colunas ao criar o gráfico, sem precisar chamar o dataframe repetidas vezes.
Por fim, usamos a função line para gerar a linha verde que representa os pontos de dados.
Criando gráficos de dispersão usando ColumnDataSource
Neste código, passamos todo o dataframe do Google para o ColumnDataSource (como no exemplo do gráfico de linha). O dataframe é salvo no ColumnDataSource na variável data. Primeiro, criamos o gráfico de linha chamando diretamente os nomes das colunas. Em seguida, usamos a função diamond para gerar os losangos vermelhos que representam os pontos individuais.
# Import packages
from bokeh.io import output_file, show
from bokeh.plotting import figure, ColumnDataSource
# Create the ColumnDataSource object
df_goog['date'] = pd.to_datetime(df_goog['date'])
data = ColumnDataSource(df_goog)
# Create time series plot
plot = figure(x_axis_type='datetime',
title='GOOG high prices ts plot',
x_axis_label = "Date",
y_axis_label = "Prices in $")
plot.line(x='date', y = 'high_goog', source = data, color = 'green')
plot.diamond(x='date', y = 'high_goog', source = data, color = 'red')
show(plot)

O gráfico mostra a evolução das ações do Google ao longo de 5 anos, com os losangos vermelhos indicando cada ponto de preço.
Conclusão
Este tutorial apresentou as estruturas de dados mais comuns que você provavelmente vai encontrar em Python e como usá-las para dar vida aos seus dados. Embora o Bokeh não seja a única opção de visualização em Python, ele se destaca do Matplotlib ou Seaborn pela facilidade de uso e recursos interativos. No próximo tutorial, você vai colocar a mão na massa com layouts para criar visualizações eficazes e interativas. Se quiser se aprofundar nas possibilidades de visualização com o Bokeh, confira o curso Interactive Data Visualization with Bokeh da DataCamp.
