Bokeh - Guia rápido

Bokeh é uma biblioteca de visualização de dados para Python. Ao contrário do Matplotlib e do Seaborn, eles também são pacotes Python para visualização de dados, o Bokeh renderiza seus gráficos usando HTML e JavaScript. Portanto, ele prova ser extremamente útil para o desenvolvimento de painéis baseados na web.

O projeto Bokeh é patrocinado pela NumFocus https://numfocus.org/.NumFocus também oferece suporte a PyData, um programa educacional, envolvido no desenvolvimento de outras ferramentas importantes, como NumPy, Pandas e muito mais. O Bokeh pode se conectar facilmente com essas ferramentas e produzir gráficos, painéis e aplicativos de dados interativos.

Características

O Bokeh converte principalmente a fonte de dados em um arquivo JSON que é usado como entrada para o BokehJS, uma biblioteca JavaScript, que por sua vez é escrita em TypeScript e renderiza as visualizações em navegadores modernos.

Alguns dos important features of Bokeh são os seguintes -

Flexibilidade

Bokeh é útil para requisitos comuns de plotagem, bem como casos de uso complexos e personalizados.

Produtividade

O Bokeh pode interagir facilmente com outras ferramentas populares do Pydata, como o Pandas e o bloco de notas Jupyter.

Interatividade

Esta é uma vantagem importante do Bokeh sobre o Matplotlib e o Seaborn, ambos produzem gráficos estáticos. O Bokeh cria gráficos interativos que mudam quando o usuário interage com eles. Você pode dar ao seu público uma ampla gama de opções e ferramentas para inferir e observar os dados de vários ângulos, de modo que o usuário possa realizar análises hipotéticas

Poderoso

Adicionando JavaScript customizado, é possível gerar visualizações para casos de uso especializados.

Compartilhável

Os gráficos podem ser incorporados na saída de Flask ou Djangoaplicativos da web habilitados. Eles também podem ser renderizados em

Jupyter

Código aberto

Bokeh é um projeto de código aberto. É distribuído sob a licença Berkeley Source Distribution (BSD). Seu código-fonte está disponível emhttps://github.com/bokeh/bokeh.

Bokeh pode ser instalado em CPython versões 2.7 e 3.5+apenas com distribuição padrão e distribuição Anaconda. A versão atual do Bokeh no momento em que este tutorial foi escrito é a versão. 1.3.4. O pacote Bokeh possui as seguintes dependências -

  • jinja2> = 2,7
  • numpy> = 1.7.1
  • embalagem> = 16,8
  • travesseiro> = 4,0
  • python-dateutil> = 2.1
  • pyyaml> = 3,10
  • seis> = 1.5.2
  • tornado> = 4,3

Geralmente, os pacotes acima são instalados automaticamente quando o Bokeh é instalado usando o gerenciador de pacotes PIP do Python, conforme mostrado abaixo -

pip3 install bokeh

Se você estiver usando a distribuição Anaconda, use o gerenciador de pacotes conda da seguinte forma -

conda install bokeh

Além das dependências acima, você pode exigir pacotes adicionais, como pandas, psutil, etc., para propósitos específicos.

Para verificar se o Bokeh foi instalado com sucesso, importe o pacote bokeh no terminal Python e verifique sua versão -

>>> import bokeh
>>> bokeh.__version__
'1.3.4'

Criar um gráfico de linha simples entre duas matrizes numpy é muito simples. Para começar, importe as seguintes funções dobokeh.plotting módulos -

from bokeh.plotting import figure, output_file, show

o figure() função cria uma nova figura para plotagem.

o output_file() função é usada para especificar um arquivo HTML para armazenar a saída.

o show() função exibe a figura Bokeh no navegador no notebook.

Em seguida, configure duas matrizes numpy onde a segunda matriz é o valor seno do primeiro.

import numpy as np
import math
x = np.arange(0, math.pi*2, 0.05)
y = np.sin(x)

Para obter um objeto Bokeh Figure, especifique o título e os rótulos dos eixos xey conforme abaixo -

p = figure(title = "sine wave example", x_axis_label = 'x', y_axis_label = 'y')

O objeto Figure contém um método line () que adiciona um glifo de linha à figura. Necessita de séries de dados para os eixos xey.

p.line(x, y, legend = "sine", line_width = 2)

Finalmente, defina o arquivo de saída e chame a função show ().

output_file("sine.html")
show(p)

Isso renderizará o gráfico de linha em 'sine.html' e será exibido no navegador.

O código completo e sua saída são os seguintes

from bokeh.plotting import figure, output_file, show
import numpy as np
import math
x = np.arange(0, math.pi*2, 0.05)
y = np.sin(x)
output_file("sine.html")
p = figure(title = "sine wave example", x_axis_label = 'x', y_axis_label = 'y')
p.line(x, y, legend = "sine", line_width = 2)
show(p)

Saída no navegador

Exibir a figura Bokeh no caderno Jupyter é muito semelhante ao acima. A única mudança que você precisa fazer é importar output_notebook ao invés de output_file do módulo bokeh.plotting.

from bokeh.plotting import figure, output_notebook, show

A chamada para a função output_notebook () define a célula de saída do notebook Jupyter como o destino para a função show () conforme mostrado abaixo -

output_notebook()
show(p)

Insira o código em uma célula do notebook e execute-o. A onda senoidal será exibida dentro do notebook.

O pacote Bokeh oferece duas interfaces com as quais várias operações de plotagem podem ser realizadas.

bokeh.models

Este módulo é uma interface de baixo nível. Ele fornece grande flexibilidade para o desenvolvedor de aplicativos no desenvolvimento de visualizações. Um gráfico Bokeh resulta em um objeto que contém aspectos visuais e de dados de uma cena que é usado pela biblioteca BokehJS. Os objetos de baixo nível que compõem um gráfico de cena Bokeh são chamados de Modelos.

bokeh.plotting

Esta é uma interface de nível superior que possui funcionalidade para compor glifos visuais. Este módulo contém a definição da classe Figure. Na verdade, é uma subclasse da classe de plotagem definida no módulo bokeh.models.

A classe de figura simplifica a criação do gráfico. Ele contém vários métodos para desenhar diferentes glifos gráficos vetorizados. Glifos são os blocos de construção da trama Bokeh, como linhas, círculos, retângulos e outras formas.

bokeh.application

Pacote Bokeh Classe de aplicativo que é uma fábrica leve para a criação de documentos Bokeh. Um documento é um contêiner para os modelos Bokeh serem refletidos na biblioteca BokehJS do lado do cliente.

bokeh.server

Ele fornece o aplicativo Bokeh Server Tornadocore personalizável. O servidor é usado para compartilhar e publicar gráficos e aplicativos interativos para um público de sua escolha.

Qualquer gráfico é geralmente feito de uma ou mais formas geométricas, como line, circle, rectangle,etc. Essas formas têm informações visuais sobre o conjunto de dados correspondente. Na terminologia Bokeh, essas formas geométricas são chamadas de glifos. Parcelas de bokeh construídas usandobokeh.plotting interfaceuse um conjunto padrão de ferramentas e estilos. No entanto, é possível personalizar os estilos usando as ferramentas de plotagem disponíveis.

Tipos de parcelas

Diferentes tipos de gráficos criados usando glifos são fornecidos abaixo -

Gráfico de linha

Este tipo de gráfico é útil para visualizar os movimentos dos pontos ao longo dos eixos xey na forma de uma linha. É usado para realizar análises de séries temporais.

Gráfico de barra

Isso normalmente é útil para indicar a contagem de cada categoria de uma coluna ou campo específico em seu conjunto de dados.

Patch plot

Este gráfico indica uma região de pontos em um determinado tom de cor. Este tipo de gráfico é usado para distinguir grupos diferentes dentro do mesmo conjunto de dados.

Gráfico de dispersão

Este tipo de gráfico é usado para visualizar a relação entre duas variáveis ​​e para indicar a força da correlação entre elas.

Diferentes gráficos de glifos são formados chamando o método apropriado da classe Figura. O objeto Figura é obtido seguindo o construtor -

from bokeh.plotting import figure
figure(**kwargs)

O objeto Figure pode ser personalizado por vários argumentos de palavra-chave.

Sr. Não Título Defina o título do enredo
1 x_axis_label Definir título do eixo x
2 y_axis_label Definir título para o eixo y
3 plot_width Definir a largura da figura
4 plot_height Definir altura da figura

Gráfico de linha

o line() methoddo objeto Figura adiciona um glifo de linha à figura Bokeh. Ele precisa dos parâmetros xey como matrizes de dados para mostrar seu relacionamento linear.

from bokeh.plotting import figure, show
fig = figure()
fig.line(x,y)
show(fig)

O código a seguir renderiza um gráfico de linha simples entre dois conjuntos de valores na forma de objetos de lista do Python -

from bokeh.plotting import figure, output_file, show
x = [1,2,3,4,5]
y = [2,4,6,8,10]
output_file('line.html')
fig = figure(title = 'Line Plot example', x_axis_label = 'x', y_axis_label = 'y')
fig.line(x,y)
show(fig)

Resultado

Gráfico de barra

O objeto de figura tem dois métodos diferentes para construir o gráfico de barra

hbar ()

As barras são mostradas horizontalmente na largura do gráfico. ohbar() method tem os seguintes parâmetros -

Sr. Não y As coordenadas y dos centros das barras horizontais.
1 altura As alturas das barras verticais.
2 direito As coordenadas x das arestas direitas.
3 esquerda As coordenadas x das bordas esquerdas.

O código a seguir é um exemplo de horizontal bar usando Bokeh.

from bokeh.plotting import figure, output_file, show
fig = figure(plot_width = 400, plot_height = 200)
fig.hbar(y = [2,4,6], height = 1, left = 0, right = [1,2,3], color = "Cyan")
output_file('bar.html')
show(fig)

Resultado

vbar ()

As barras são mostradas verticalmente na altura do gráfico. ovbar() method tem os seguintes parâmetros -

Sr. Não x As coordenadas x dos centros das barras verticais.
1 largura As larguras das barras verticais.
2 topo As coordenadas y das arestas superiores.
3 inferior As coordenadas y das arestas inferiores.

O código a seguir exibe vertical bar plot -

from bokeh.plotting import figure, output_file, show
fig = figure(plot_width = 200, plot_height = 400)
fig.vbar(x = [1,2,3], width = 0.5, bottom = 0, top = [2,4,6], color = "Cyan")
output_file('bar.html')
show(fig)

Resultado

Patch plot

Um gráfico que sombreia uma região do espaço com uma cor específica para mostrar uma região ou um grupo com propriedades semelhantes é denominado como um gráfico de correção em Bokeh. O objeto Figure possui os métodos patch () e patches () para esse propósito.

fragmento()

Este método adiciona glifo de patch a determinada figura. O método possui os seguintes argumentos -

1 x As coordenadas x para os pontos do patch.
2 y As coordenadas y para os pontos do patch.

Um simples patch plot é obtido pelo seguinte código Python -

from bokeh.plotting import figure, output_file, show
p = figure(plot_width = 300, plot_height = 300)
p.patch(x = [1, 3,2,4], y = [2,3,5,7], color = "green")
output_file('patch.html')
show(p)

Resultado

patches ()

Este método é usado para desenhar vários patches poligonais. Necessita dos seguintes argumentos -

1 xs As coordenadas x para todos os patches, fornecidas como uma “lista de listas”.
2 sim As coordenadas y para todos os patches, fornecidas como uma “lista de listas”.

Como exemplo do método patches (), execute o seguinte código -

from bokeh.plotting import figure, output_file, show
xs = [[5,3,4], [2,4,3], [2,3,5,4]]
ys = [[6,4,2], [3,6,7], [2,4,7,8]]
fig = figure()
fig.patches(xs, ys, fill_color = ['red', 'blue', 'black'], line_color = 'white')
output_file('patch_plot.html')
show(fig)

Resultado

Marcadores de dispersão

Gráficos de dispersão são muito comumente usados ​​para determinar a relação bivariada entre duas variáveis. A interatividade aprimorada é adicionada a eles usando Bokeh. O gráfico de dispersão é obtido chamando o método scatter () do objeto Figura. Ele usa os seguintes parâmetros -

1 x valores ou nomes de campo das coordenadas x do centro
2 y valores ou nomes de campo de coordenadas y de centro
3 Tamanho valores ou nomes de campo de tamanhos em unidades de tela
4 marcador valores ou nomes de campo de tipos de marcadores
5 cor definir preenchimento e cor da linha

As seguintes constantes de tipo de marcador são definidas no Bokeh: -

  • Asterisk
  • Circle
  • CircleCross
  • CircleX
  • Cross
  • Dash
  • Diamond
  • DiamondCross
  • Hex
  • InvertedTriangle
  • Square
  • SquareCross
  • SquareX
  • Triangle
  • X

Seguir o código Python gera um gráfico de dispersão com marcas circulares.

from bokeh.plotting import figure, output_file, show
fig = figure()
fig.scatter([1, 4, 3, 2, 5], [6, 5, 2, 4, 7], marker = "circle", size = 20, fill_color = "grey")
output_file('scatter.html')
show(fig)

Resultado

Parcelas de área são regiões preenchidas entre duas séries que compartilham um índice comum. A classe Figure de Bokeh tem dois métodos, como segue -

varea ()

A saída do método varea () é uma área direcionada vertical que tem uma matriz de coordenadas x e duas matrizes de coordenadas y, y1 e y2, que serão preenchidas entre elas.

1 x As coordenadas x para os pontos da área.
2 y1 As coordenadas y para os pontos de um lado da área.
3 y2 As coordenadas y para os pontos do outro lado da área.

Exemplo

from bokeh.plotting import figure, output_file, show
fig = figure()
x = [1, 2, 3, 4, 5]
y1 = [2, 6, 4, 3, 5]
y2 = [1, 4, 2, 2, 3]
fig.varea(x = x,y1 = y1,y2 = y2)
output_file('area.html')
show(fig)

Resultado

harea ()

O método harea (), por outro lado, precisa dos parâmetros x1, x2 e y.

1 x1 As coordenadas x para os pontos de um lado da área.
2 x2 As coordenadas x para os pontos do outro lado da área.
3 y As coordenadas y para os pontos da área.

Exemplo

from bokeh.plotting import figure, output_file, show
fig = figure()
y = [1, 2, 3, 4, 5]
x1 = [2, 6, 4, 3, 5]
x2 = [1, 4, 2, 2, 3]
fig.harea(x1 = x1,x2 = x2,y = y)
output_file('area.html')
show(fig)

Resultado

O objeto de figura tem muitos métodos usando os glifos vetorizados de diferentes formas, como circle, rectangle, polygon, etc. podem ser desenhados.

Os seguintes métodos estão disponíveis para desenho circle glyphs -

círculo()

o circle() método adiciona um glifo de círculo à figura e precisa de xe ycoordenadas de seu centro. Além disso, pode ser configurado com a ajuda de parâmetros comofill_color, line-color, line_width etc.

circle_cross ()

O método circle_cross () adiciona o glifo do círculo com uma cruz '+' no centro.

circle_x ()

O método circle_x () adiciona um círculo com um 'X' cruzado no centro.

Exemplo

O exemplo a seguir mostra o uso de vários glifos de círculo adicionados à figura Bokeh -

from bokeh.plotting import figure, output_file, show
plot = figure(plot_width = 300, plot_height = 300)
plot.circle(x = [1, 2, 3], y = [3,7,5], size = 20, fill_color = 'red')
plot.circle_cross(x = [2,4,6], y = [5,8,9], size = 20, fill_color = 'blue',fill_alpha = 0.2, line_width = 2)
plot.circle_x(x = [5,7,2], y = [2,4,9], size = 20, fill_color = 'green',fill_alpha = 0.6, line_width = 2)
show(plot)

Resultado

É possível renderizar rectangle, ellipse and polygonsem uma figura Bokeh. orect() methodda classe Figura adiciona um glifo retângulo com base nas coordenadas xey de centro, largura e altura. O método square (), por outro lado, possui o parâmetro de tamanho para decidir as dimensões.

Os métodos elipse () e oval () adicionam uma elipse e um glifo oval. Eles usam uma assinatura semelhante à de rect () com os parâmetros x, y, w e h. Além disso, o parâmetro de ângulo determina a rotação da horizontal.

Exemplo

O código a seguir mostra o uso de diferentes shape glyph methods -

from bokeh.plotting import figure, output_file, show
fig = figure(plot_width = 300, plot_height = 300)
fig.rect(x = 10,y = 10,width = 100, height = 50, width_units = 'screen', height_units = 'screen')
fig.square(x = 2,y = 3,size = 80, color = 'red')
fig.ellipse(x = 7,y = 6, width = 30, height = 10, fill_color = None, line_width = 2)
fig.oval(x = 6,y = 6,width = 2, height = 1, angle = -0.4)
show(fig)

Resultado

o arc() methoddesenha um arco de linha simples com base nas coordenadas xey, ângulos iniciais e finais e raio. Os ângulos são dados em radianos, enquanto o raio pode ser em unidades de tela ou unidades de dados. A cunha é um arco preenchido.

o wedge() methodtem as mesmas propriedades do método arc (). Ambos os métodos fornecem propriedade opcional de direção, que pode ser relógio ou anticlock que determina a direção da renderização do arco / cunha. A função annular_wedge () renderiza uma área preenchida entre arcos de raio interno e externo.

Exemplo

Aqui está um exemplo de arc e wedge glyphs adicionado à figura Bokeh -

from bokeh.plotting import figure, output_file, show
import math
fig = figure(plot_width = 300, plot_height = 300)
fig.arc(x = 3, y = 3, radius = 50, radius_units = 'screen', start_angle = 0.0, end_angle = math.pi/2)
fig.wedge(x = 3, y = 3, radius = 30, radius_units = 'screen',
start_angle = 0, end_angle = math.pi, direction = 'clock')
fig.annular_wedge(x = 3,y = 3, inner_radius = 100, outer_radius = 75,outer_radius_units = 'screen',
inner_radius_units = 'screen',start_angle = 0.4, end_angle = 4.5,color = "green", alpha = 0.6)
show(fig)

Resultado

o bokeh.plotting API oferece suporte a métodos de renderização seguindo curvas especializadas -

beizer ()

Este método adiciona uma curva de Bézier ao objeto de figura. Uma curva de Bézier é uma curva paramétrica usada em computação gráfica. Outros usos incluem o design de fontes e animação de computador, design de interface de usuário e para suavizar a trajetória do cursor.

Em gráficos vetoriais, as curvas de Bézier são usadas para modelar curvas suaves que podem ser dimensionadas indefinidamente. Um "Caminho" é uma combinação de curvas de Bézier vinculadas.

O método beizer () tem os seguintes parâmetros que são definidos -

1 x0 As coordenadas x dos pontos iniciais.
2 y0 As coordenadas y dos pontos de partida ..
3 x1 As coordenadas x dos pontos finais.
4 y1 As coordenadas y dos pontos finais.
5 cx0 As coordenadas x dos primeiros pontos de controle.
6 cy0 As coordenadas y dos primeiros pontos de controle.
7 cx1 As coordenadas x dos segundos pontos de controle.
8 cy1 As coordenadas y dos segundos pontos de controle.

O valor padrão para todos os parâmetros é Nenhum.

Exemplo

O código a seguir gera uma página HTML mostrando uma curva de Bézier e parábola no gráfico Bokeh -

x = 2
y = 4
xp02 = x+0.4
xp01 = x+0.1
xm01 = x-0.1
yp01 = y+0.2
ym01 = y-0.2
fig = figure(plot_width = 300, plot_height = 300)
fig.bezier(x0 = x, y0 = y, x1 = xp02, y1 = y, cx0 = xp01, cy0 = yp01,
cx1 = xm01, cy1 = ym01, line_color = "red", line_width = 2)

Resultado

quadrático()

Este método adiciona um parabola glyphpara bokeh figura. A função tem os mesmos parâmetros de beizer (), excetocx0 e cx1.

Exemplo

O código fornecido a seguir gera uma curva quadrática.

x = 2
y = 4
xp02 = x + 0.3
xp01 = x + 0.2
xm01 = x - 0.4
yp01 = y + 0.1
ym01 = y - 0.2
x = x,
y = y,
xp02 = x + 0.4,
xp01 = x + 0.1,
yp01 = y + 0.2,
fig.quadratic(x0 = x, y0 = y, x1 = x + 0.4, y1 = y + 0.01, cx = x + 0.1,
cy = y + 0.2, line_color = "blue", line_width = 3)

Resultado

Intervalos numéricos de eixos de dados de um gráfico são definidos automaticamente pelo Bokeh levando em consideração o conjunto de dados em processo. No entanto, às vezes você pode querer definir o intervalo de valores nos eixos xey explicitamente. Isso é feito atribuindo as propriedades x_range e y_range a uma função figure ().

Esses intervalos são definidos com a ajuda da função range1d ().

Exemplo

xrange = range1d(0,10)

Para usar este objeto de intervalo como propriedade x_range, use o código a seguir -

fig = figure(x,y,x_range = xrange)

Neste capítulo, discutiremos sobre vários tipos de eixos.

Sr. Não Eixos Descrição
1 Eixos Categóricos Os gráficos de bokeh mostram dados numéricos ao longo dos eixos x e y. Para usar dados categóricos ao longo de qualquer um dos eixos, precisamos especificar um FactorRange para especificar as dimensões categóricas de um deles.
2 Eixos de escala de registro Se houver uma relação de lei de potência entre as séries de dados xey, é desejável usar escalas logarítmicas em ambos os eixos.
3 Machados duplos Pode ser necessário mostrar vários eixos que representam faixas variadas em uma única figura de gráfico. O objeto de figura pode ser configurado definindoextra_x_range e extra_y_range propriedades

Eixos Categóricos

Nos exemplos até agora, os gráficos Bokeh mostram dados numéricos ao longo dos eixos xe y. Para usar dados categóricos ao longo de qualquer um dos eixos, precisamos especificar um FactorRange para especificar as dimensões categóricas de um deles. Por exemplo, para usar strings na lista fornecida para o eixo x -

langs = ['C', 'C++', 'Java', 'Python', 'PHP']
fig = figure(x_range = langs, plot_width = 300, plot_height = 300)

Exemplo

Com o exemplo a seguir, um gráfico de barra simples é exibido mostrando o número de alunos matriculados em vários cursos oferecidos.

from bokeh.plotting import figure, output_file, show
langs = ['C', 'C++', 'Java', 'Python', 'PHP']
students = [23,17,35,29,12]
fig = figure(x_range = langs, plot_width = 300, plot_height = 300)
fig.vbar(x = langs, top = students, width = 0.5)
show(fig)

Resultado

Para mostrar cada barra em cores diferentes, defina a propriedade de cor da função vbar () para a lista de valores de cor.

cols = ['red','green','orange','navy', 'cyan']
fig.vbar(x = langs, top = students, color = cols,width=0.5)

Resultado

Para renderizar uma barra empilhada vertical (ou horizontal) usando a função vbar_stack () ou hbar_stack (), defina stackers property para lista de campos para empilhar sucessivamente e source property para um objeto dict contendo valores correspondentes a cada campo.

No exemplo a seguir, as vendas são um dicionário que mostra os números das vendas de três produtos em três meses.

from bokeh.plotting import figure, output_file, show
products = ['computer','mobile','printer']
months = ['Jan','Feb','Mar']
sales = {'products':products,
   'Jan':[10,40,5],
   'Feb':[8,45,10],
   'Mar':[25,60,22]}
cols = ['red','green','blue']#,'navy', 'cyan']
fig = figure(x_range = products, plot_width = 300, plot_height = 300)
fig.vbar_stack(months, x = 'products', source = sales, color = cols,width = 0.5)
show(fig)

Resultado

Um gráfico de barras agrupadas é obtido especificando um deslocamento visual para as barras com a ajuda da função dodge () em bokeh.transform módulo.

o dodge() functionintroduz um deslocamento relativo para cada gráfico de barra, obtendo assim uma impressão visual do grupo. No exemplo a seguir,vbar() glyph é separado por um deslocamento de 0,25 para cada grupo de barras de um determinado mês.

from bokeh.plotting import figure, output_file, show
from bokeh.transform import dodge
products = ['computer','mobile','printer']
months = ['Jan','Feb','Mar']
sales = {'products':products,
   'Jan':[10,40,5],
   'Feb':[8,45,10],
   'Mar':[25,60,22]}
fig = figure(x_range = products, plot_width = 300, plot_height = 300)
fig.vbar(x = dodge('products', -0.25, range = fig.x_range), top = 'Jan',
   width = 0.2,source = sales, color = "red")
fig.vbar(x = dodge('products', 0.0, range = fig.x_range), top = 'Feb',
   width = 0.2, source = sales,color = "green")
fig.vbar(x = dodge('products', 0.25, range = fig.x_range), top = 'Mar',
   width = 0.2,source = sales,color = "blue")
show(fig)

Resultado

Eixos de escala de registro

Quando os valores em um dos eixos de um gráfico crescem exponencialmente com o aumento linear dos valores de outro, geralmente é necessário que os dados do eixo anterior sejam exibidos em uma escala logarítmica. Por exemplo, se existe uma relação de lei de potência entre as séries de dados xey, é desejável usar escalas logísticas em ambos os eixos.

A função figure () da API Bokeh.plotting aceita x_axis_type e y_axis_type como argumentos que podem ser especificados como eixo log, passando "log" para o valor de qualquer um desses parâmetros.

A primeira figura mostra o gráfico entre x e 10x em uma escala linear. Na segunda figura y_axis_type é definido como 'log'

from bokeh.plotting import figure, output_file, show
x = [0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
y = [10**i for i in x]
fig = figure(title = 'Linear scale example',plot_width = 400, plot_height = 400)
fig.line(x, y, line_width = 2)
show(fig)

Resultado

Agora mude a função figure () para configurar y_axis_type = 'log'

fig = figure(title = 'Linear scale example',plot_width = 400, plot_height = 400, y_axis_type = "log")

Resultado

Machados duplos

Em certas situações, pode ser necessário mostrar vários eixos que representam faixas variadas em uma única figura de gráfico. O objeto de figura pode ser configurado definindoextra_x_range e extra_y_rangepropriedades. Ao adicionar um novo glifo à figura, esses intervalos nomeados são usados.

Tentamos exibir uma curva seno e uma linha reta no mesmo gráfico. Ambos os glifos têm eixos y com intervalos diferentes. As séries de dados xey para a curva senoidal e reta são obtidas pelo seguinte -

from numpy import pi, arange, sin, linspace
x = arange(-2*pi, 2*pi, 0.1)
y = sin(x)
y2 = linspace(0, 100, len(y))

Aqui, o gráfico entre x e y representa a relação seno e o gráfico entre x e y2 é uma linha reta. O objeto Figura é definido com y_range explícito e um glifo de linha representando a curva senoidal é adicionado da seguinte forma -

fig = figure(title = 'Twin Axis Example', y_range = (-1.1, 1.1))
fig.line(x, y, color = "red")

Precisamos de um alcance extra y. É definido como -

fig.extra_y_ranges = {"y2": Range1d(start = 0, end = 100)}

Para adicionar eixo y adicional no lado direito, use o método add_layout (). Adicione um novo glifo de linha representando xey2 à figura.

fig.add_layout(LinearAxis(y_range_name = "y2"), 'right')
fig.line(x, y2, color = "blue", y_range_name = "y2")

Isso resultará em um gráfico com eixos y gêmeos. O código completo e a saída são os seguintes -

from numpy import pi, arange, sin, linspace
x = arange(-2*pi, 2*pi, 0.1)
y = sin(x)
y2 = linspace(0, 100, len(y))
from bokeh.plotting import output_file, figure, show
from bokeh.models import LinearAxis, Range1d
fig = figure(title='Twin Axis Example', y_range = (-1.1, 1.1))
fig.line(x, y, color = "red")
fig.extra_y_ranges = {"y2": Range1d(start = 0, end = 100)}
fig.add_layout(LinearAxis(y_range_name = "y2"), 'right')
fig.line(x, y2, color = "blue", y_range_name = "y2")
show(fig)

Resultado

As anotações são pedaços de texto explicativo adicionados ao diagrama. O gráfico Bokeh pode ser anotado especificando o título do gráfico, rótulos para os eixos xey, bem como inserindo rótulos de texto em qualquer lugar na área do gráfico.

O título do gráfico, bem como os rótulos dos eixos xey, podem ser fornecidos no próprio construtor de Figura.

fig = figure(title, x_axis_label, y_axis_label)

No gráfico a seguir, essas propriedades são definidas conforme mostrado abaixo -

from bokeh.plotting import figure, output_file, show
import numpy as np
import math
x = np.arange(0, math.pi*2, 0.05)
y = np.sin(x)
fig = figure(title = "sine wave example", x_axis_label = 'angle', y_axis_label = 'sin')
fig.line(x, y,line_width = 2)
show(p)

Resultado

O texto do título e os rótulos dos eixos também podem ser especificados atribuindo valores de string apropriados às propriedades correspondentes do objeto de figura.

fig.title.text = "sine wave example"
fig.xaxis.axis_label = 'angle'
fig.yaxis.axis_label = 'sin'

Também é possível especificar localização, alinhamento, fonte e cor do título.

fig.title.align = "right"
fig.title.text_color = "orange"
fig.title.text_font_size = "25px"
fig.title.background_fill_color = "blue"

Adicionar legendas à figura do enredo é muito fácil. Temos que usar a propriedade legend de qualquer método de glifo.

Abaixo, temos três curvas de glifo no gráfico com três legendas diferentes -

from bokeh.plotting import figure, output_file, show
import numpy as np
import math
x = np.arange(0, math.pi*2, 0.05)
fig = figure()
fig.line(x, np.sin(x),line_width = 2, line_color = 'navy', legend = 'sine')
fig.circle(x,np.cos(x), line_width = 2, line_color = 'orange', legend = 'cosine')
fig.square(x,-np.sin(x),line_width = 2, line_color = 'grey', legend = '-sine')
show(fig)

Resultado

Em todos os exemplos acima, os dados a serem plotados foram fornecidos na forma de listas Python ou matrizes numpy. Também é possível fornecer a fonte de dados na forma do objeto pandas DataFrame.

DataFrame é uma estrutura de dados bidimensional. As colunas no dataframe podem ser de diferentes tipos de dados. A biblioteca Pandas tem funções para criar dataframe de várias fontes, como arquivo CSV, planilha do Excel, tabela SQL, etc.

Para o propósito do exemplo a seguir, estamos usando um arquivo CSV que consiste em duas colunas que representam um número xe 10x. O arquivo test.csv é o seguinte -

x,pow
0.0,1.0
0.5263157894736842,3.3598182862837818
1.0526315789473684,11.28837891684689
1.5789473684210527,37.926901907322495
2.1052631578947367,127.42749857031335
2.631578947368421,428.1332398719391
3.1578947368421053,1438.449888287663
3.6842105263157894,4832.930238571752
4.2105263157894735,16237.76739188721
4.7368421052631575,54555.947811685146

Devemos ler este arquivo em um objeto dataframe usando a função read_csv () no pandas.

import pandas as pd
df = pd.read_csv('test.csv')
print (df)

O dataframe aparece como abaixo -

x        pow
0 0.000000 1.000000
1 0.526316 3.359818
2 1.052632 11.288379
3 1.578947 37.926902
4 2.105263 127.427499
5 2.631579 428.133240
6 3.157895 1438.449888
7 3.684211 4832.930239
8 4.210526 16237.767392
9 4.736842 54555.947812

As colunas 'x' e 'pow' são usadas como série de dados para o glifo de linha na figura do gráfico bokeh.

from bokeh.plotting import figure, output_file, show
p = figure()
x = df['x']
y = df['pow']
p.line(x,y,line_width = 2)
p.circle(x, y,size = 20)
show(p)

Resultado

A maioria dos métodos de plotagem na API Bokeh são capazes de receber parâmetros de fonte de dados por meio do objeto ColumnDatasource. Faz compartilhamento de dados entre plotagens e 'DataTables'.

Um ColumnDatasource pode ser considerado um mapeamento entre o nome da coluna e a lista de dados. Um objeto Python dict com uma ou mais chaves de string e listas ou matrizes numpy como valores é passado para o construtor ColumnDataSource.

Exemplo

Abaixo está o exemplo

from bokeh.models import ColumnDataSource
data = {'x':[1, 4, 3, 2, 5],
   'y':[6, 5, 2, 4, 7]}
cds = ColumnDataSource(data = data)

Este objeto é então usado como valor da propriedade source em um método de glifo. O código a seguir gera um gráfico de dispersão usando ColumnDataSource.

from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource
data = {'x':[1, 4, 3, 2, 5],
   'y':[6, 5, 2, 4, 7]}
cds = ColumnDataSource(data = data)
fig = figure()
fig.scatter(x = 'x', y = 'y',source = cds, marker = "circle", size = 20, fill_color = "grey")
show(fig)

Resultado

Em vez de atribuir um dicionário Python para ColumnDataSource, podemos usar um Pandas DataFrame para ele.

Vamos usar 'test.csv' (usado anteriormente nesta seção) para obter um DataFrame e usá-lo para obter ColumnDataSource e renderizar o gráfico de linha.

from bokeh.plotting import figure, output_file, show
import pandas as pd
from bokeh.models import ColumnDataSource
df = pd.read_csv('test.csv')
cds = ColumnDataSource(df)
fig = figure(y_axis_type = 'log')
fig.line(x = 'x', y = 'pow',source = cds, line_color = "grey")
show(fig)

Resultado

Freqüentemente, você pode desejar obter um gráfico pertencente a uma parte dos dados que satisfaça certas condições, em vez de todo o conjunto de dados. O objeto da classe CDSView definida no módulo bokeh.models retorna um subconjunto de ColumnDatasource sob consideração aplicando um ou mais filtros sobre ele.

IndexFilter é o tipo de filtro mais simples. Você deve especificar os índices apenas das linhas do conjunto de dados que deseja usar ao plotar a figura.

O exemplo a seguir demonstra o uso de IndexFilter para configurar um CDSView. A figura resultante mostra um glifo de linha entre as séries de dados xey do ColumnDataSource. Um objeto de exibição é obtido aplicando filtro de índice sobre ele. A visualização é usada para plotar o glifo do círculo como resultado do IndexFilter.

Exemplo

from bokeh.models import ColumnDataSource, CDSView, IndexFilter
from bokeh.plotting import figure, output_file, show
source = ColumnDataSource(data = dict(x = list(range(1,11)), y = list(range(2,22,2))))
view = CDSView(source=source, filters = [IndexFilter([0, 2, 4,6])])
fig = figure(title = 'Line Plot example', x_axis_label = 'x', y_axis_label = 'y')
fig.circle(x = "x", y = "y", size = 10, source = source, view = view, legend = 'filtered')
fig.line(source.data['x'],source.data['y'], legend = 'unfiltered')
show(fig)

Resultado

Para escolher apenas as linhas da fonte de dados, que satisfaçam uma determinada condição booleana, aplique um BooleanFilter.

Uma instalação típica do Bokeh consiste em vários conjuntos de dados de amostra no diretório sampledata. Para o exemplo a seguir, usamosunemployment1948conjunto de dados fornecido na forma de desemprego1948.csv. Ele armazena a porcentagem anual de desemprego nos EUA desde 1948. Queremos gerar um gráfico apenas para o ano 1980 em diante. Para isso, um objeto CDSView é obtido aplicando BooleanFilter sobre a fonte de dados fornecida.

from bokeh.models import ColumnDataSource, CDSView, BooleanFilter
from bokeh.plotting import figure, show
from bokeh.sampledata.unemployment1948 import data
source = ColumnDataSource(data)
booleans = [True if int(year) >= 1980 else False for year in
source.data['Year']]
print (booleans)
view1 = CDSView(source = source, filters=[BooleanFilter(booleans)])
p = figure(title = "Unemployment data", x_range = (1980,2020), x_axis_label = 'Year', y_axis_label='Percentage')
p.line(x = 'Year', y = 'Annual', source = source, view = view1, color = 'red', line_width = 2)
show(p)

Resultado

Para adicionar mais flexibilidade na aplicação de filtro, Bokeh fornece uma classe CustomJSFilter com a ajuda da qual a fonte de dados pode ser filtrada com uma função JavaScript definida pelo usuário.

O exemplo abaixo usa os mesmos dados de desemprego dos EUA. Definindo um CustomJSFilter para traçar os números do desemprego do ano 1980 e depois.

from bokeh.models import ColumnDataSource, CDSView, CustomJSFilter
from bokeh.plotting import figure, show
from bokeh.sampledata.unemployment1948 import data
source = ColumnDataSource(data)
custom_filter = CustomJSFilter(code = '''
   var indices = [];

   for (var i = 0; i < source.get_length(); i++){
      if (parseInt(source.data['Year'][i]) > = 1980){
         indices.push(true);
      } else {
         indices.push(false);
      }
   }
   return indices;
''')
view1 = CDSView(source = source, filters = [custom_filter])
p = figure(title = "Unemployment data", x_range = (1980,2020), x_axis_label = 'Year', y_axis_label = 'Percentage')
p.line(x = 'Year', y = 'Annual', source = source, view = view1, color = 'red', line_width = 2)
show(p)

As visualizações do bokeh podem ser adequadamente organizadas em diferentes opções de layout. Esses layouts, bem como os modos de dimensionamento, resultam em gráficos e widgets redimensionados automaticamente de acordo com o tamanho da janela do navegador. Para uma aparência consistente, todos os itens em um layout devem ter o mesmo modo de dimensionamento. Os widgets (botões, menus, etc.) são mantidos em uma caixa de widget separada e não na figura do gráfico.

O primeiro tipo de layout é o layout de coluna, que exibe as figuras do gráfico verticalmente. ocolumn() function é definido em bokeh.layouts módulo e leva a seguinte assinatura -

from bokeh.layouts import column
col = column(children, sizing_mode)

children - Lista de parcelas e / ou widgets.

sizing_mode- determina como os itens no layout são redimensionados. Os valores possíveis são "fixed", "stretch_both", "scale_width", "scale_height", "scale_both". O padrão é “fixo”.

O código a seguir produz duas figuras Bokeh e as coloca em um layout de coluna para que sejam exibidas verticalmente. Os glifos de linha que representam a relação seno e cos entre as séries de dados xey são exibidos em Cada figura.

from bokeh.plotting import figure, output_file, show
from bokeh.layouts import column
import numpy as np
import math
x = np.arange(0, math.pi*2, 0.05)
y1 = np.sin(x)
y2 = np.cos(x)
fig1 = figure(plot_width = 200, plot_height = 200)
fig1.line(x, y1,line_width = 2, line_color = 'blue')
fig2 = figure(plot_width = 200, plot_height = 200)
fig2.line(x, y2,line_width = 2, line_color = 'red')
c = column(children = [fig1, fig2], sizing_mode = 'stretch_both')
show(c)

Resultado

Da mesma forma, o layout de linha organiza os gráficos horizontalmente, para os quais row() functionconforme definido no módulo bokeh.layouts é usado. Como você poderia pensar, também leva dois argumentos (semelhantes acolumn() function) - filhos e sizing_mode.

As curvas seno e cos, conforme mostrado verticalmente no diagrama acima, agora são exibidas horizontalmente no layout de linha com o seguinte código

from bokeh.plotting import figure, output_file, show
from bokeh.layouts import row
import numpy as np
import math
x = np.arange(0, math.pi*2, 0.05)
y1 = np.sin(x)
y2 = np.cos(x)
fig1 = figure(plot_width = 200, plot_height = 200)
fig1.line(x, y1,line_width = 2, line_color = 'blue')
fig2 = figure(plot_width = 200, plot_height = 200)
fig2.line(x, y2,line_width = 2, line_color = 'red')
r = row(children = [fig1, fig2], sizing_mode = 'stretch_both')
show(r)

Resultado

O pacote Bokeh também possui layout de grade. Ele contém várias figuras de plot (bem como widgets) em uma grade bidimensional de linhas e colunas. ogridplot() function no módulo bokeh.layouts retorna uma grade e uma única barra de ferramentas unificada que pode ser posicionada com a ajuda da propriedade toolbar_location.

Isso é diferente do layout de linha ou coluna, onde cada gráfico mostra sua própria barra de ferramentas. A função grid () também usa os parâmetros children e sizing_mode, onde children é uma lista de listas. Certifique-se de que cada sublista tenha as mesmas dimensões.

No código a seguir, quatro relacionamentos diferentes entre as séries de dados xey são plotados em uma grade de duas linhas e duas colunas.

from bokeh.plotting import figure, output_file, show
from bokeh.layouts import gridplot
import math
x = list(range(1,11))

y1 = x
y2 =[11-i for i in x]
y3 = [i*i for i in x]
y4 = [math.log10(i) for i in x]

fig1 = figure(plot_width = 200, plot_height = 200)
fig1.line(x, y1,line_width = 2, line_color = 'blue')
fig2 = figure(plot_width = 200, plot_height = 200)
fig2.circle(x, y2,size = 10, color = 'green')
fig3 = figure(plot_width = 200, plot_height = 200)
fig3.circle(x,y3, size = 10, color = 'grey')
fig4 = figure(plot_width = 200, plot_height = 200, y_axis_type = 'log')
fig4.line(x,y4, line_width = 2, line_color = 'red')
grid = gridplot(children = [[fig1, fig2], [fig3,fig4]], sizing_mode = 'stretch_both')
show(grid)

Resultado

Quando um gráfico Bokeh é renderizado, normalmente uma barra de ferramentas aparece no lado direito da figura. Ele contém um conjunto padrão de ferramentas. Primeiramente, a posição da barra de ferramentas pode ser configurada pela propriedade toolbar_location na função figure (). Esta propriedade pode assumir um dos seguintes valores -

  • "above"
  • "below"
  • "left"
  • "right"
  • "None"

Por exemplo, a seguinte declaração fará com que a barra de ferramentas seja exibida abaixo do gráfico -

Fig = figure(toolbar_location = "below")

Esta barra de ferramentas pode ser configurada de acordo com os requisitos, adicionando os requisitos de várias ferramentas definidas no módulo bokeh.models. Por exemplo -

Fig.add_tools(WheelZoomTool())

As ferramentas podem ser classificadas nas seguintes categorias -

  • Ferramentas Pan / Drag
  • Clique / Toque em Ferramentas
  • Ferramentas de rolagem / pinça
Ferramenta Descrição Ícone

BoxSelectTool

Nome: 'box_select'

permite ao usuário definir uma região de seleção retangular arrastando o botão esquerdo do mouse

LassoSelectTool

nome: 'lasso_select

permite ao usuário definir uma região arbitrária para seleção arrastando o botão esquerdo do mouse

PanTool

nome: 'pan', 'xpan', 'ypan',

permite ao usuário deslocar o gráfico arrastando o botão esquerdo do mouse

TapTool

nome: 'tap

permite que o usuário selecione em pontos únicos clicando com o botão esquerdo do mouse

WheelZoomTool

nome: 'wheel_zoom', 'xwheel_zoom', 'ywheel_zoom'

amplie e afaste o gráfico, centralizado na localização atual do mouse.

WheelPanTool

nome: 'xwheel_pan', 'ywheel_pan'

converter a janela de plotagem ao longo da dimensão especificada sem alterar a proporção da janela.

ResetTool

nome: 'reset'

restaura os intervalos do gráfico para seus valores originais.

SaveTool

nome: 'salvar'

permite que o usuário salve uma imagem PNG do gráfico.

ZoomInTool

nome: 'zoom_in', 'xzoom_in', 'yzoom_in'

A ferramenta de zoom aumentará o zoom do gráfico em x, y ou ambas as coordenadas

ZoomOutTool

nome: 'zoom_out', 'xzoom_out', 'yzoom_out'

A ferramenta de afastamento irá diminuir o zoom do gráfico em x, y ou ambas as coordenadas

CrosshairTool

nome: 'crosshair'

desenha uma anotação em cruz sobre o gráfico, centralizado na posição atual do mouse.

A aparência padrão de um gráfico Bokeh pode ser personalizada configurando várias propriedades com o valor desejado. Essas propriedades são principalmente de três tipos -

Propriedades da linha

A tabela a seguir lista várias propriedades relacionadas ao glifo de linha.

1 cor da linha a cor é usada para traçar linhas com
2 espessura da linha Isso é usado em unidades de pixels como largura de traço de linha
3 line_alpha Entre 0 (transparente) e 1 (opaco), atua como um ponto flutuante
4 line_join como juntar os segmentos do caminho. Os valores definidos são: 'miter' (miter_join), 'round' (round_join), 'bevel' (bevel_join)
5 line_cap como encerrar os segmentos de caminho. Os valores definidos são: 'butt' (butt_cap), 'round' (round_cap), 'square' (square_cap)
6 line_dash B Isto é usado para um estilo de linha. Os valores definidos são: 'sólido', 'tracejado', 'pontilhado', 'dotdash', 'dashdot'
7 line_dash_offset A distância na linha_dash em pixels a partir da qual o padrão deve começar

Propriedades de preenchimento

Várias propriedades de preenchimento estão listadas abaixo -

1 fill_color Isso é usado para preencher caminhos com
2 fill_alpha Entre 0 (transparente) e 1 (opaco), atua como um ponto flutuante

Propriedades do texto

Existem muitas propriedades relacionadas ao texto, conforme listado na tabela a seguir -

1 text_font nome da fonte, por exemplo, 'times', 'helvetica'
2 text_font_size tamanho da fonte em px, em ou pt, por exemplo, '12pt', '1.5em'
3 text_font_style estilo de fonte para usar 'normal' 'itálico' 'negrito'
4 cor do texto Isso é usado para renderizar texto com
5 text_alpha Entre 0 (transparente) e 1 (opaco), este é um ponto flutuante
6 alinhamento de texto ponto de ancoragem horizontal para texto - 'esquerda', 'direita', 'centro'
7 text_baseline ponto de ancoragem vertical para o texto 'superior', 'meio', 'inferior', 'alfabético', 'suspenso'

Vários glifos em um gráfico podem ser identificados pela propriedade da legenda e aparecem como um rótulo por padrão na posição superior direita da área do gráfico. Esta legenda pode ser personalizada pelos seguintes atributos -

1 legend.label_text_font alterar a fonte da etiqueta padrão para o nome da fonte especificada
2 legend.label_text_font_size tamanho da fonte em pontos
3 legend.location defina o rótulo no local especificado.
4 legend.title definir título para rótulo de legenda
5 legend.orientation definido como horizontal (padrão) ou vertical
6 legend.clicking_policy especifica o que deve acontecer quando a legenda é clicada ocultar: oculta o glifo correspondente à legenda sem som: silencia o glifo correspondente a legendtd>

Exemplo

O código de exemplo para personalização de legenda é o seguinte -

from bokeh.plotting import figure, output_file, show
import math
x2 = list(range(1,11))
y4 = [math.pow(i,2) for i in x2]
y2 = [math.log10(pow(10,i)) for i in x2]
fig = figure(y_axis_type = 'log')
fig.circle(x2, y2,size = 5, color = 'blue', legend = 'blue circle')
fig.line(x2,y4, line_width = 2, line_color = 'red', legend = 'red line')
fig.legend.location = 'top_left'
fig.legend.title = 'Legend Title'
fig.legend.title_text_font = 'Arial'
fig.legend.title_text_font_size = '20pt'
show(fig)

Resultado

O módulo bokeh.models.widgets contém definições de objetos GUI semelhantes a elementos de formulário HTML, como botão, controle deslizante, caixa de seleção, botão de rádio, etc. Esses controles fornecem interface interativa para um gráfico. A chamada de processamento, como modificação de dados de plotagem, alteração de parâmetros de plotagem, etc., pode ser realizada por funções JavaScript personalizadas executadas em eventos correspondentes.

Bokeh permite que a funcionalidade de retorno de chamada seja definida com dois métodos -

  • Use o CustomJS callback para que a interatividade funcione em documentos HTML autônomos.

  • Usar Bokeh server e configurar manipuladores de eventos.

Nesta seção, veremos como adicionar widgets Bokeh e atribuir callbacks JavaScript.

Botão

Este widget é um botão clicável geralmente usado para invocar um manipulador de retorno de chamada definido pelo usuário. O construtor leva os seguintes parâmetros -

Button(label, icon, callback)

O parâmetro label é uma string usada como legenda do botão e callback é a função JavaScript personalizada a ser chamada quando clicado.

No exemplo a seguir, um gráfico e um widget de botão são exibidos no layout da coluna. O próprio gráfico renderiza um glifo de linha entre as séries de dados xey.

Uma função JavaScript personalizada chamada 'callback' foi definida usando CutomJS() function. Ele recebe referência ao objeto que acionou o callback (neste caso o botão) na variável de formulário cb_obj.

Esta função altera os dados de origem ColumnDataSource e, finalmente, emite essa atualização nos dados de origem.

from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.plotting import Figure, output_file, show
from bokeh.models.widgets import Button

x = [x*0.05 for x in range(0, 200)]
y = x

source = ColumnDataSource(data=dict(x=x, y=y))
plot = Figure(plot_width=400, plot_height=400)
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)

callback = CustomJS(args=dict(source=source), code="""
   var data = source.data;
   x = data['x']
   y = data['y']
   for (i = 0; i < x.length; i++) {
      y[i] = Math.pow(x[i], 4)
   }
   source.change.emit();
""")

btn = Button(label="click here", callback=callback, name="1")

layout = column(btn , plot)
show(layout)

Saída (inicial)

Clique no botão na parte superior do gráfico e veja a figura atualizada do gráfico que se parece com o seguinte -

Saída (após clique)

Slider

Com a ajuda de um controle deslizante, é possível selecionar um número entre as propriedades iniciais e finais atribuídas a ele.

Slider(start, end, step, value)

No exemplo a seguir, registramos uma função de retorno de chamada no evento on_change do controle deslizante. O valor numérico instantâneo do Slider está disponível para o manipulador na forma de cb_obj.value que é usado para modificar os dados ColumnDatasource. A figura do gráfico é atualizada continuamente conforme você desliza a posição.

from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.plotting import Figure, output_file, show
from bokeh.models.widgets import Slider

x = [x*0.05 for x in range(0, 200)]
y = x

source = ColumnDataSource(data=dict(x=x, y=y))
plot = Figure(plot_width=400, plot_height=400)
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)

handler = CustomJS(args=dict(source=source), code="""
   var data = source.data;
   var f = cb_obj.value
   var x = data['x']
   var y = data['y']
   for (var i = 0; i < x.length; i++) {
      y[i] = Math.pow(x[i], f)
   }
   source.change.emit();
""")

slider = Slider(start=0.0, end=5, value=1, step=.25, title="Slider Value")

slider.js_on_change('value', handler)
layout = column(slider, plot)
show(layout)

Resultado

RadioGroup

Este widget apresenta uma coleção de botões de alternância mutuamente exclusivos, mostrando botões circulares à esquerda da legenda.

RadioGroup(labels, active)

Onde, rótulos é uma lista de legendas e ativo é o índice da opção selecionada.

Selecione

Este widget é uma lista suspensa simples de itens de string, um dos quais pode ser selecionado. A string selecionada aparece na janela superior e é o parâmetro de valor.

Select(options, value)

A lista de elementos de string na lista suspensa é fornecida na forma de um objeto de lista de opções.

A seguir está um exemplo combinado de botão de opção e widgets de seleção, ambos fornecendo três relacionamentos diferentes entre as séries de dados xey. oRadioGroup e Select widgets são registrados com os respectivos manipuladores por meio do método on_change ().

from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.plotting import Figure, output_file, show
from bokeh.models.widgets import RadioGroup, Select

x = [x*0.05 for x in range(0, 200)]
y = x

source = ColumnDataSource(data=dict(x=x, y=y))

plot = Figure(plot_width=400, plot_height=400)
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)

radiohandler = CustomJS(args=dict(source=source), code="""
   var data = source.data;
   console.log('Tap event occurred at x-position: ' + cb_obj.active);
   //plot.title.text=cb_obj.value;
   x = data['x']
   y = data['y']
   if (cb_obj.active==0){
      for (i = 0; i < x.length; i++) {
         y[i] = x[i];
      }
   }
   if (cb_obj.active==1){
      for (i = 0; i < x.length; i++) {
         y[i] = Math.pow(x[i], 2)
      }
   }
   if (cb_obj.active==2){
      for (i = 0; i < x.length; i++) {
         y[i] = Math.pow(x[i], 4)
      }
   }
   source.change.emit();
""")

selecthandler = CustomJS(args=dict(source=source), code="""
   var data = source.data;
   console.log('Tap event occurred at x-position: ' + cb_obj.value);
   //plot.title.text=cb_obj.value;
   x = data['x']
   y = data['y']
   if (cb_obj.value=="line"){
      for (i = 0; i < x.length; i++) {
         y[i] = x[i];
      }
   }
   if (cb_obj.value=="SquareCurve"){
      for (i = 0; i < x.length; i++) {
         y[i] = Math.pow(x[i], 2)
      }
   }
   if (cb_obj.value=="CubeCurve"){
      for (i = 0; i < x.length; i++) {
         y[i] = Math.pow(x[i], 4)
      }
   }
   source.change.emit();
""")

radio = RadioGroup(
   labels=["line", "SqureCurve", "CubeCurve"], active=0)
radio.js_on_change('active', radiohandler)
select = Select(title="Select:", value='line', options=["line", "SquareCurve", "CubeCurve"])
select.js_on_change('value', selecthandler)

layout = column(radio, select, plot)
show(layout)

Resultado

Widget de guia

Assim como em um navegador, cada guia pode mostrar uma página da web diferente, o widget Guia é um modelo Bokeh que fornece uma visualização diferente para cada figura. No exemplo a seguir, duas figuras de gráfico de curvas de seno e cosseno são renderizadas em duas guias diferentes -

from bokeh.plotting import figure, output_file, show
from bokeh.models import Panel, Tabs
import numpy as np
import math
x=np.arange(0, math.pi*2, 0.05)
fig1=figure(plot_width=300, plot_height=300)

fig1.line(x, np.sin(x),line_width=2, line_color='navy')

tab1 = Panel(child=fig1, title="sine")
fig2=figure(plot_width=300, plot_height=300)
fig2.line(x,np.cos(x), line_width=2, line_color='orange')
tab2 = Panel(child=fig2, title="cos")

tabs = Tabs(tabs=[ tab1, tab2 ])

show(tabs)

Resultado

A arquitetura Bokeh tem um design desacoplado em que objetos como gráficos e glifos são criados usando Python e convertidos em JSON para serem consumidos por BokehJS client library.

No entanto, é possível manter os objetos em python e no navegador sincronizados uns com os outros com a ajuda de Bokeh Server. Ele permite a resposta a eventos de interface do usuário (UI) gerados em um navegador com todo o poder do python. Ele também ajuda a enviar automaticamente atualizações do lado do servidor para os widgets ou gráficos em um navegador.

Um servidor Bokeh usa o código do aplicativo escrito em Python para criar documentos Bokeh. Cada nova conexão de um navegador cliente resulta no servidor Bokeh criando um novo documento, apenas para aquela sessão.

Primeiro, temos que desenvolver um código de aplicativo para ser servido ao navegador do cliente. O código a seguir renderiza um glifo de linha de onda senoidal. Junto com o gráfico, um controle deslizante também é renderizado para controlar a frequência da onda senoidal. A função de retorno de chamadaupdate_data() atualizações ColumnDataSource dados tomando o valor instantâneo do controle deslizante como frequência atual.

import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import row, column
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import Slider, TextInput
from bokeh.plotting import figure
N = 200
x = np.linspace(0, 4*np.pi, N)
y = np.sin(x)
source = ColumnDataSource(data = dict(x = x, y = y))
plot = figure(plot_height = 400, plot_width = 400, title = "sine wave")
plot.line('x', 'y', source = source, line_width = 3, line_alpha = 0.6)
freq = Slider(title = "frequency", value = 1.0, start = 0.1, end = 5.1, step = 0.1)
def update_data(attrname, old, new):
   a = 1
   b = 0
   w = 0
   k = freq.value
   x = np.linspace(0, 4*np.pi, N)
   y = a*np.sin(k*x + w) + b
   source.data = dict(x = x, y = y)
freq.on_change('value', update_data)
curdoc().add_root(row(freq, plot, width = 500))
curdoc().title = "Sliders"

Em seguida, inicie o servidor Bokeh seguindo a linha de comando -

Bokeh serve –show sliders.py

O servidor Bokeh começa a rodar e servir o aplicativo em localhost: 5006 / sliders. O log do console mostra a seguinte tela -

C:\Users\User>bokeh serve --show scripts\sliders.py
2019-09-29 00:21:35,855 Starting Bokeh server version 1.3.4 (running on Tornado 6.0.3)
2019-09-29 00:21:35,875 Bokeh app running at: http://localhost:5006/sliders
2019-09-29 00:21:35,875 Starting Bokeh server with process id: 3776
2019-09-29 00:21:37,330 200 GET /sliders (::1) 699.99ms
2019-09-29 00:21:38,033 101 GET /sliders/ws?bokeh-protocol-version=1.0&bokeh-session-id=VDxLKOzI5Ppl9kDvEMRzZgDVyqnXzvDWsAO21bRCKRZZ (::1) 4.00ms
2019-09-29 00:21:38,045 WebSocket connection opened
2019-09-29 00:21:38,049 ServerConnection created

Abra seu navegador favorito e insira o endereço acima. O gráfico da onda senoidal é exibido da seguinte forma -

Você pode tentar mudar a frequência para 2 rolando o controle deslizante.

O aplicativo Bokeh fornece vários subcomandos a serem executados na linha de comando. A tabela a seguir mostra os subcomandos -

1 Html Crie arquivos HTML para um ou mais aplicativos
2 informação imprimir informações da configuração do servidor Bokeh
3 json Crie arquivos JSON para um ou mais aplicativos
4 png Crie arquivos PNG para um ou mais aplicativos
5 dados de amostra Baixe os conjuntos de dados de amostra de bokeh
6 segredo Crie uma chave secreta Bokeh para usar com o servidor Bokeh
7 servir Execute um servidor Bokeh hospedando um ou mais aplicativos
8 estático Servir ativos estáticos (JavaScript, CSS, imagens, fontes, etc.) usados ​​pela biblioteca BokeJS
9 SVG Crie arquivos SVG para um ou mais aplicativos

O comando a seguir gera um arquivo HTML para o script Python com uma figura Bokeh.

C:\python37>bokeh html -o app.html app.py

Adicionar a opção show abre automaticamente o arquivo HTML no navegador. Da mesma forma, o script Python é convertido em arquivos PNG, SVG, JSON com o subcomando correspondente.

Para exibir informações do servidor Bokeh, use o subcomando info da seguinte maneira -

C:\python37>bokeh info
Python version : 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)]
IPython version : (not installed)
Tornado version : 6.0.3
Bokeh version : 1.3.4
BokehJS static path : c:\python37\lib\site-packages\bokeh\server\static
node.js version : (not installed)
npm version : (not installed)

Para experimentar vários tipos de plotagens, o site Bokeh https://bokeh.pydata.orgdisponibiliza conjuntos de dados de amostra. Eles podem ser baixados para a máquina local pelo subcomando sampledata.

C:\python37>bokeh info

Os seguintes conjuntos de dados são baixados na pasta C: \ Users \ User \ .bokeh \ data -

AAPL.csv                                     airports.csv
airports.json                                CGM.csv
FB.csv                                       gapminder_fertility.csv
gapminder_life_expectancy.csv                gapminder_population.csv
gapminder_regions.csv                        GOOG.csv
haarcascade_frontalface_default.xml          IBM.csv
movies.db                                    MSFT.csv
routes.csv                                   unemployment09.csv
us_cities.json                               US_Counties.csv
world_cities.csv
WPP2012_SA_DB03_POPULATION_QUINQUENNIAL.csv

O subcomando secreto gera uma chave secreta para ser usada junto com o subcomando serve com a variável de ambiente SECRET_KEY.

Além dos subcomandos descritos acima, os gráficos Bokeh podem ser exportados para os formatos de arquivo PNG e SVG usando a função export (). Para esse propósito, a instalação local do Python deve ter as seguintes bibliotecas de dependência.

PhantomJS

PhantomJS é uma API JavaScript que permite navegação automatizada, capturas de tela, comportamento do usuário e asserções. Ele é usado para executar testes de unidade baseados em navegador. O PhantomJS é baseado no WebKit, fornecendo um ambiente de navegação semelhante para diferentes navegadores e oferece suporte rápido e nativo para vários padrões da web: manipulação de DOM, seletor de CSS, JSON, Canvas e SVG. Em outras palavras, o PhantomJS é um navegador da web sem interface gráfica de usuário.

Travesseiro

Pillow, uma biblioteca de imagens Python (anteriormente conhecida como PIL) é uma biblioteca gratuita para a linguagem de programação Python que fornece suporte para abrir, manipular e salvar muitos formatos de arquivo de imagem diferentes. (incluindo PPM, PNG, JPEG, GIF, TIFF e BMP.) Alguns de seus recursos são manipulações por pixel, manipulação de máscara e transparência, filtragem de imagem, aprimoramento de imagem, etc.

A função export_png () gera imagem PNG no formato RGBA a partir do layout. Esta função usa o navegador sem cabeça Webkit para renderizar o layout na memória e, em seguida, capturar uma imagem. A imagem gerada terá as mesmas dimensões do layout de origem. Certifique-se de que Plot.background_fill_color e Plot.border_fill_color são propriedades para Nenhum.

from bokeh.io import export_png
export_png(plot, filename = "file.png")

É possível que a saída do gráfico HTML5 Canvas com um elemento SVG possa ser editado usando programas como o Adobe Illustrator. Os objetos SVG também podem ser convertidos em PDFs. Aqui, canvas2svg, uma biblioteca JavaScript é usada para simular o elemento Canvas normal e seus métodos com um elemento SVG. Como os PNGs, para criar um SVG com um fundo transparente, as propriedades Plot.background_fill_color e Plot.border_fill_color devem ser Nenhum.

O backend SVG é ativado primeiro definindo o atributo Plot.output_backend como "svg".

plot.output_backend = "svg"

Para exportação sem cabeça, Bokeh tem uma função de utilitário, export_svgs (). Esta função baixará todos os gráficos habilitados para SVG em um layout como arquivos SVG distintos.

from bokeh.io import export_svgs
plot.output_backend = "svg"
export_svgs(plot, filename = "plot.svg")

Plots e dados na forma de documentos autônomos, bem como aplicativos Bokeh, podem ser incorporados em documentos HTML.

O documento autônomo é um gráfico Bokeh ou documento não suportado pelo servidor Bokeh. As interações em tal plotagem são puramente na forma de JS customizado e não em Python Python.

Plotagens Bokeh e documentos suportados pelo servidor Bokeh também podem ser incorporados. Esses documentos contêm retornos de chamada Python executados no servidor.

No caso de documentos independentes, um código HTML bruto representando um gráfico Bokeh é obtido pela função file_html ().

from bokeh.plotting import figure
from bokeh.resources import CDN
from bokeh.embed import file_html
fig = figure()
fig.line([1,2,3,4,5], [3,4,5,2,3])
string = file_html(plot, CDN, "my plot")

O valor de retorno da função file_html () pode ser salvo como um arquivo HTML ou pode ser usado para renderizar por meio de rotas de URL no aplicativo Flask.

No caso de documento autônomo, sua representação JSON pode ser obtida pela função json_item ().

from bokeh.plotting import figure
from bokeh.embed import file_html
import json
fig = figure()
fig.line([1,2,3,4,5], [3,4,5,2,3])
item_text = json.dumps(json_item(fig, "myplot"))

Essa saída pode ser usada pela função Bokeh.embed.embed_item em uma página da web -

item = JSON.parse(item_text);
Bokeh.embed.embed_item(item);

Os aplicativos Bokeh no Bokeh Server também podem ser incorporados para que uma nova sessão e um Documento sejam criados em cada carregamento de página para que uma sessão existente específica seja carregada. Isso pode ser feito com a função server_document (). Ele aceita a URL para um aplicativo de servidor Bokeh e retorna um script que irá incorporar novas sessões desse servidor sempre que o script for executado.

o server_document() functionaceita parâmetro de URL. Se for definido como 'padrão', o URL padrão http: // localhost: 5006 / será usado.

from bokeh.embed import server_document
script = server_document("http://localhost:5006/sliders")

A função server_document () retorna uma tag de script da seguinte forma -

<script
   src="http://localhost:5006/sliders/autoload.js?bokeh-autoload-element=1000&bokeh-app-path=/sliders&bokeh-absolute-url=https://localhost:5006/sliders"
   id="1000">
</script>

O Bokeh integra-se bem com uma ampla variedade de outras bibliotecas, permitindo que você use a ferramenta mais adequada para cada tarefa. O fato de o Bokeh gerar JavaScript torna possível combinar a saída do Bokeh com uma ampla variedade de bibliotecas JavaScript, como o PhosphorJS.

Datashader (https://github.com/bokeh/datashader) é outra biblioteca com a qual a saída Bokeh pode ser estendida. É uma biblioteca Python que pré-renderiza grandes conjuntos de dados como uma imagem raster de grande porte. Essa capacidade supera a limitação do navegador quando se trata de dados muito grandes. O Datashader inclui ferramentas para construir gráficos Bokeh interativos que re-renderizam dinamicamente essas imagens ao aplicar zoom e panorâmica no Bokeh, tornando prático trabalhar com conjuntos de dados arbitrariamente grandes em um navegador da web.

Outra biblioteca é a Holoviews ( (http://holoviews.org/), que fornece uma interface declarativa concisa para a construção de plotagens Bokeh, especialmente no caderno Jupyter, facilitando a prototipagem rápida de figuras para análise de dados.

Quando é necessário usar grandes conjuntos de dados para criar visualizações com a ajuda do Bokeh, a interação pode ser muito lenta. Para isso, pode-se habilitar o suporte para Web Graphics Library (WebGL).

WebGL é uma API JavaScript que renderiza conteúdo no navegador usando GPU (unidade de processamento gráfico). Este plugin padronizado está disponível em todos os navegadores modernos.

Para ativar o WebGL, tudo o que você precisa fazer é definir a propriedade output_backend do objeto Bokeh Figure como 'webgl'.

fig = figure(output_backend="webgl")

No exemplo a seguir, traçamos um scatter glyph consistindo em 10.000 pontos com a ajuda de suporte WebGL.

import numpy as np
from bokeh.plotting import figure, show, output_file
N = 10000
x = np.random.normal(0, np.pi, N)
y = np.sin(x) + np.random.normal(0, 0.2, N)
output_file("scatterWebGL.html")
p = figure(output_backend="webgl")
p.scatter(x, y, alpha=0.1)
show(p)

Resultado

A biblioteca Bokeh Python e bibliotecas para outras linguagens como R, Scala e Julia interagem principalmente com o BokehJS em alto nível. Um programador Python não precisa se preocupar com JavaScript ou desenvolvimento web. No entanto, pode-se usar a API BokehJS para fazer o desenvolvimento de JavaScript puro usando BokehJS diretamente.

Objetos BokehJS, como glifos e widgets, são construídos mais ou menos de forma semelhante à API Bokeh Python. Normalmente, qualquer ClassName Python está disponível comoBokeh.ClassNamedo JavaScript. Por exemplo, um objeto Range1d obtido em Python.

xrange = Range1d(start=-0.5, end=20.5)

É obtido de forma equivalente com BokehJS como -

var xrange = new Bokeh.Range1d({ start: -0.5, end: 20.5 });

Seguir o código JavaScript quando incorporado em um arquivo HTML renderiza um gráfico de linha simples no navegador.

Primeiro inclua todas as bibliotecas BokehJS na seção <head> .. </head> da página da web conforme abaixo

<head>
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-1.3.4.min.js"></script>
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.3.4.min.js"></script>
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-tables-1.3.4.min.js"></script>
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-gl-1.3.4.min.js"></script>
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-api-1.3.4.min.js"></script>
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-api-1.3.4.min.js"></script>
</head>

Na seção do corpo, os trechos seguintes de JavaScript constroem várias partes de um gráfico Bokeh.

<script>
// create some data and a ColumnDataSource
var x = Bokeh.LinAlg.linspace(-0.5, 20.5, 10);
var y = x.map(function (v) { return v * 0.5 + 3.0; });
var source = new Bokeh.ColumnDataSource({ data: { x: x, y: y } });
// make the plot
var plot = new Bokeh.Plot({
   title: "BokehJS Plot",
   plot_width: 400,
   plot_height: 400
});

// add axes to the plot
var xaxis = new Bokeh.LinearAxis({ axis_line_color: null });
var yaxis = new Bokeh.LinearAxis({ axis_line_color: null });
plot.add_layout(xaxis, "below");
plot.add_layout(yaxis, "left");

// add a Line glyph
var line = new Bokeh.Line({
   x: { field: "x" },
   y: { field: "y" },
   line_color: "#666699",
   line_width: 2
});
plot.add_glyph(line, source);

Bokeh.Plotting.show(plot);
</script>

Salve o código acima como uma página da web e abra-o em um navegador de sua escolha.