
Nos nossos tutoriais anteriores de Bokeh, vimos como dar os primeiros passos com Bokeh e criar gráficos básicos de dispersão e linha. Além do vasto leque de possibilidades de visualização, o Bokeh também permite hospedar apps em seus próprios servidores, conectando Python ao navegador.
Vamos começar criando o app e executando-o nos servidores do Bokeh para compartilhar com colegas. Para saber mais sobre como o servidor do Bokeh funciona, confira a documentação do Bokeh.
Fundamentos do Bokeh Server
O Bokeh converte objetos (como gráficos, widgets, eixos e praticamente tudo o que você cria) em formato JSON.
O servidor do Bokeh converte o código Python que você escreve em um documento JSON. Esse documento é renderizado em JavaScript usando a biblioteca cliente do Bokeh (BokehJS) para que os usuários vejam a aplicação no navegador.
A vantagem do Bokeh é que ele cuida da parte em JavaScript. Assim, você não precisa conhecer JavaScript para criar um app! A imagem a seguir resume como o servidor do Bokeh funciona.

Fonte: The Bokeh Server
Como criar e rodar uma aplicação Bokeh
A estrutura geral de um app em Bokeh é:
- Criar gráficos e widgets: este é o primeiro passo para criar um app Bokeh. Tenha em mente o gráfico que você quer apresentar.
- Definir funções de callback: uma função de callback instrui o app sobre como responder à interação do usuário. Por exemplo, ao selecionar um ticker diferente em um gráfico de séries temporais, o gráfico deve atualizar com os novos dados.
- Criar layouts: os layouts ajudam a apresentar os gráficos de forma eficaz e atraente.
Criando um app web de análise do mercado de ações em Bokeh
Descrição do projeto
Nesta seção, vamos mostrar como criar um app web simples e publicá-lo para que analistas financeiros possam usar.
Imagine que você trabalha na Big Money Inc — uma grande gestora de ativos. Sua gerente ouviu seus colegas elogiarem suas habilidades em Python. Agora ela quer que você crie um app de ações para que os analistas financeiros da empresa comparem dois papéis. Ela acredita que os analistas podem ganhar tempo comparando rapidamente qualquer ação com outra similar do mesmo setor. Por exemplo, comparar Apple com Microsoft e escolher a melhor para montar carteiras de clientes. A comparação deve incluir métricas básicas, como:
- Gráficos de tendência do preço de fechamento
- Correlação
- Média (retorno esperado)
- Desvio padrão (risco esperado)
Deve haver uma forma de personalizar o período de análise de maneira interativa. Por exemplo, o usuário deve conseguir comparar o desempenho de duas ações na última semana, mês, ano ou qualquer período que preferir. Você precisa garantir que o app esteja disponível para todos na empresa, o que significa fazer o deploy em um serviço de nuvem.
Pré-requisitos
- Entendimento básico de Bokeh.
- Algum conhecimento de Python.
- Instalação dos pacotes indicados em nosso tutorial de introdução ao Bokeh.
Visão geral do app web de mercado de ações
O app web resolve o estudo de caso financeiro descrito acima. Ele permite selecionar dois tickers e visualizar estatísticas descritivas (como média e desvio padrão) de preços e retornos, gráficos de correlação e gráficos de tendência de preços para as ações escolhidas. A interatividade vem da seleção de diferentes combinações de tickers e períodos (nos gráficos de tendência). O app ficará assim:

Criando o projeto do app web de mercado de ações em Bokeh
1. Crie uma pasta de projeto e dê o nome SelectStock.
2. Abra a pasta do projeto e crie um arquivo chamado main.py.
3. Salve uma cópia dos dados de mercado de ações na pasta do projeto como "all_stocks_5yr.csv".
Salve também uma cópia dos tickers. O arquivo ticker.py contém a lista de tickers. Há apenas 505 tickers; incluir a lista completa diretamente no main.py deixaria o código pesado. Vale a pena salvar a lista em um arquivo separado e importá-la quando necessário.
Abra o arquivo main.py no seu editor favorito, como Spyder, Atom ou Sublime Text.
Importar pacotes
Digite o código a seguir no arquivo main.py. Ele importa os pacotes e os tickers necessários para criar o app web:
# Import the required packages
import pandas as pd
from functools import lru_cache
from bokeh.io import curdoc
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, PreText, Select, Div
from bokeh.plotting import figure
# load the list of tickers
import tickers
tickers = tickers.tickers
Ler e carregar dados
Crie uma função para evitar que um ticker seja comparado com ele mesmo:
# Create a function to ensure that a ticker is not compared to itself
def foo(val, lst):
return [x for x in lst if x != val]
Add the following code to read and load data for the webapp:
# A function to read and load data
# Note the use of @lru_cache() decorator is to cache the data and speed up reloads
@lru_cache()
def load_ticker(ticker):
data = pd.read_csv('all_stocks_5yr.csv', parse_dates=['date'])
data = data.set_index('date')
data = data[data['Name'] == ticker]
return pd.DataFrame({ticker: data.close, ticker+'_returns': data.close.diff()})
# A function to create a dataframe for the selected tickers
@lru_cache()
def get_data(t1, t2):
df1 = load_ticker(t1)
df2 = load_ticker(t2)
data = pd.concat([df1, df2], axis=1)
data = data.dropna()
data['t1'] = data[t1]
data['t2'] = data[t2]
data['t1_returns'] = data[t1+'_returns']
data['t2_returns'] = data[t2+'_returns']
return data
# Put data into a ColumnDataSource
source = ColumnDataSource(
data=dict(date=[], t1=[], t2=[], t1_returns=[], t2_returns=[]))
Criar widgets
# set up widgets
stats = PreText(text='', width=500)
ticker1 = Select(value='AAPL', options=foo('GOOG', tickers))
ticker2 = Select(value='GOOG', options=foo('AAPL', tickers))
Os widgets permitem que o usuário selecione o primeiro e o segundo ticker para comparação. Depois de selecionar os tickers, o Bokeh pode gerar os gráficos.
Criar gráficos
# set up plots
tools = 'pan,wheel_zoom,xbox_select,reset'
corr = figure(width=400, height=350,
tools='pan,wheel_zoom,box_select,reset', output_backend='webgl')
corr.diamond('t1_returns', 't2_returns', size=2, source=source, color="red",
selection_color="orange", alpha=0.6, nonselection_alpha=0.1, selection_alpha=0.4)
time_series1 = figure(width=900, height=200, tools=tools,
x_axis_type='datetime', active_drag="xbox_select", output_backend='webgl')
time_series1.line('date', 't1', source=source, color='orange')
time_series2 = figure(width=900, height=200, tools=tools,
x_axis_type='datetime', active_drag="xbox_select", output_backend='webgl')
time_series2.x_range = time_series1.x_range
time_series2.line('date', 't2', source=source, color='green')
Nesse código, primeiro definimos as ferramentas que acompanham os gráficos. O gráfico de correlação é o primeiro, com figure() especificando width = 400 e height = 350. O gráfico de correlação usa marcadores em formato de losango.
Usamos o glyph line para criar os gráficos de séries temporais dos tickers. O intervalo das séries é igualado para permitir uma comparação adequada.
# Define callbacks
def change_ticker1(attrname, old, new):
ticker2.options = foo(new, tickers)
update()
def change_ticker2(attrname, old, new):
ticker1.options = foo(new, tickers)
update()
def update(selected=None):
t1, t2 = ticker1.value, ticker2.value
df = get_data(t1, t2)
data = df[['t1', 't2', 't1_returns', 't2_returns']]
source.data = data
update_stats(df, t1, t2)
corr.title.text = '%s returns vs. %s returns' % (t1, t2)
time_series1.title.text, time_series2.title.text = t1, t2
def update_stats(data, t1, t2):
stats.text = str(data[[t1, t2, t1+'_returns', t2+'_returns']].describe())
ticker1.on_change('value', change_ticker1)
ticker2.on_change('value', change_ticker2)
def selection_change(attrname, old, new):
t1, t2 = ticker1.value, ticker2.value
data = get_data(t1, t2)
selected = source.selected.indices
if selected:
data = data.iloc[selected, :]
update_stats(data, t1, t2)
source.selected.on_change('indices', selection_change)
Na seção de callbacks, as duas primeiras funções definem as respostas para mudanças do ticker 1 e do ticker 2, respectivamente.
A função update() atualiza os gráficos sempre que o usuário escolhe uma combinação diferente de tickers; a função update_stats() atualiza as estatísticas quando um novo conjunto é selecionado; e a função selection_change() atualiza todo o app quando o usuário altera os tickers.
Configurar o layout
O primeiro passo é dar um título ao app, com instruções sobre como interagir com ele. A função Div permite inserir o texto e definir altura e largura, além de outras personalizações.
# set up layout
# Add a title message to the app
div = Div(
text="""
<p>Select two Stocks to compare key Statistics:</p>
""",
width=900,
height=30,
)
# Create layouts
app_title = div
widgets = column(ticker1, ticker2, stats)
main_row = row(widgets, corr)
series = column(time_series1, time_series2)
layout = column(app_title, main_row, series)
O layout do app combina as funções column e row.
Primeiro, o título fica no topo. A linha principal vem em seguida (contendo as estatísticas descritivas e o gráfico de correlação). A próxima linha traz o primeiro gráfico de série temporal (para o ticker 1) e a última linha, o gráfico de série temporal do segundo ticker.
Inicializar o app
Esta etapa inicializa o app web quando ele é chamado no servidor.
# initialize the app
update()
curdoc().add_root(layout)
curdoc().title = "Compare Stocks"
Fazendo o deploy do app web
Para testar seu app web, você pode fazer o deploy na sua máquina local. Para isso, abra o Anaconda Prompt ou o terminal de sua preferência. Navegue até o diretório que contém a pasta do projeto "SelectStock". Você pode fazer isso digitando:
cd "System path to where the SelectStock folder is contained"
ex.: cd "C:\Users\... \SelectStock"
Digite o seguinte comando para executar o app web:
bokeh serve --show SelectStock
Como alternativa, você pode entrar na pasta SelectStock e executar o arquivo main.py:
Bokeh serve --show main.py
Isso vai abrir o app web no navegador padrão em:
http://localhost:5006/SelectStock ou
Você está usando o Bokeh Server para rodar e publicar seu app web.
Você também pode fazer o deploy do app usando serviços como o Heroku.
Conclusão
Neste tutorial, você aprendeu os fundamentos de como construir e publicar suas próprias aplicações Bokeh na máquina local. Mostramos como juntar tudo o que você aprendeu para criar um app prático, divertido e interativo que conquista os usuários.
A melhor forma de evoluir rápido na programação é construir projetos como este logo após aprender um conceito ou ferramenta. Essa abordagem prática garante um bom domínio da ferramenta ou habilidade e ainda permite mostrar a empregadores em potencial o que você vem fazendo.
Se quiser aprender mais sobre Bokeh, você pode ler este livro. Ou, melhor ainda, faça o curso Interactive Visualization with Bokeh da DataCamp. Ele aprofunda o Bokeh e mostra como criar gráficos mais avançados. Você também pode ir além e aprender a construir seus próprios apps web com Bokeh usando dados em tempo real.
