Bokehを伸ばす

Bokehは、ブラウザ内で複雑なインタラクティブな可視化およびデータアプリケーションを作成するために使用できる豊富な内蔵タイプを提供しています。しかしながら、いくつかの機能および特性は、ユーザが望むものである可能性があるが、コアライブラリには現れないかもしれないが、それらが専門的すぎるためであるか、またはリソースが不足しているためである。幸いにも、カスタムユーザ拡張を作成することによって、Bokehを拡張することができる。

  • 既存のBokehモデルを修正する行為

  • 第三者JavaScriptライブラリをPythonに接続するために新しいモデルを追加します

  • 特定の分野の用例のために高度に特化されたモデルを作成する

カスタム拡張は、標準バージョンと共に作成して使用することができ、開発環境を設定したり、ソースコードから何も構築する必要がありません。それらはBokeh開発に参加する最も簡単な方法を提供する。拡張Bokehのしきい値を下げることによって、ユーザは、コアチームを待つことなく、新しい特性および改善された機能(いつかコアライブラリに追加される候補になる可能性がある)を“試用”することができる。

Bokehモデルの構造

Pythonモデル

ほとんどの場合、Python Bokehモデルは完全に宣言的クラスです。カスタム拡張はサブクラスを作成することで作成される Model (またはそのサブクラス)、JavaScript側ミラーリングの属性を宣言するための特殊なクラス属性を含む。すべての利用可能な属性タイプは bokeh.core.properties マニュアルの一節を参考にする。

以下は、スライダのためのカスタム読み取りを作成する小さな例である。

from bokeh.core.properties import String, Instance
from bokeh.models import HTMLBox, Slider

class Custom(HTMLBox):

    text = String(default="Custom text")

    slider = Instance(Slider)

DOMのレイアウトに参加できるカスタム拡張を作成したいので HTMLBox それがそうです。2つの属性を追加しました:a String 読み取りのためにテキストメッセージを構成するには、以下の操作を実行してください Instance 一つ収容できる Slider それがそうです。JavaScript Slider オブジェクト、このオブジェクトはPythonに対応しています Slider ご利用いただけます。

JavaScriptモデルとビュー

Python側は主に宣言的であり、実際のコードはあまり多くありませんが、JavaScript側ではモデルを実現するためのコードが必要です。適切であれば、対応するビューのコードも提供されなければならない。

以下はアノテーション付きタイピングスクリプト実現であり,使用するためのものである. Custom そのようなものです CustomView それがそうです。内蔵モデルに対して,このコードは最終的なBokehJSスクリプトに直接含まれる.次節では,このコードをカスタム拡張にどのように接続するかを知る.

import {HTMLBox, HTMLBoxView} from "models/layouts/html_box"

import {div} from "core/dom"
import * as p from "core/properties"

export class CustomView extends HTMLBoxView {

  connect_signals(): void {
    super.connect_signals()

    // Set BokehJS listener so that when the Bokeh slider has a change
    // event, we can process the new data.
    this.connect(this.model.slider.change, () => {
      this.render()
      this.invalidate_layout()
    })
  }

  render(): void {
    // BokehjS Views create <div> elements by default, accessible as
    // ``this.el``. Many Bokeh views ignore this default <div>, and instead
    // do things like draw to the HTML canvas. In this case though, we change
    // the contents of the <div>, based on the current slider value.
    super.render()

    this.el.appendChild(div({
      style: {
        padding: '2px',
        color: '#b88d8e',
        backgroundColor: '#2a3153',
      },
    }, `${this.model.text}: ${this.model.slider.value}`))
  }
}

export class Custom extends HTMLBox {
  slider: {value: string}

  // The ``__name__`` class attribute should generally match exactly the name
  // of the corresponding Python class. Note that if using TypeScript, this
  // will be automatically filled in during compilation, so except in some
  // special cases, this shouldn't be generally included manually, to avoid
  // typos, which would prohibit serialization/deserialization of this model.
  static __name__ = "Surface3d"

  static init_Custom(): void {
    // If there is an associated view, this is typically boilerplate.
    this.prototype.default_view = CustomView

    // The this.define() block adds corresponding "properties" to the JS model.
    // These should normally line up 1-1 with the Python model class. Most property
    // types have counterparts, e.g. bokeh.core.properties.String will be
    // ``p.String`` in the JS implementation. Any time the JS type system is not
    // yet as complete, you can use ``p.Any`` as a "wildcard" property type.
    this.define<Custom.Props>({
      text:   [ p.String ],
      slider: [ p.Any    ],
    })
  }
}

これを組み合わせて

内蔵されたBokehモデルの場合、BoehJSでの実装は、構築プロセスによって対応するPythonモデルと自動的に一致します。JavaScriptをPythonモデルに接続するためには、追加のステップが必要です。Pythonクラスにはクラス属性という名前があるはずです __implementation__ その値は、クライアントモデルおよび任意のオプションのビューを定義するタイプスクリプト(またはJavaScript)コードである。

上のタイピングコードが1つのファイルに保存されていると仮定する. custom.ts 完全なPythonクラスは以下のようになる可能性があります。

from bokeh.core.properties import String, Instance
from bokeh.models import HTMLBox, Slider

class Custom(HTMLBox):

    __implementation__ = "custom.ts"

    text = String(default="Custom text")

    slider = Instance(Slider)

これがPythonモジュールで定義されている場合 custom.py 現在、カスタム拡張は、内蔵Bokehモデルを使用するように使用することができます。

from bokeh.io import show, output_file
from bokeh.layouts import column
from bokeh.models import Slider

slider = Slider(start=0, end=10, step=0.1, value=0, title="value")

custom = Custom(text="Special Slider Display", slider=slider)

layout = column(slider, custom)

show(layout)

これにより,以下の出力が生じる.実現したJavaScriptコードは自動的に提示された文書に含まれる.スライダをドラッグして、スライド移動時の特殊ヘッダ更新を表示します。

指定実現言語

もし __implementation__ 既知の拡張子の1つで終わる単行です .js あるいは、あるいは .ts これを文書名と解釈する.対応するファイルを開き、ファイル拡張子に従ってそのコンテンツを適切にコンパイルする。

そうでなければ,実現がクラスでインライン化されていれば,クラスを用いて明示的にソースコードを提供する言語を用いることができる. JavaScript あるいは、あるいは TypeScript 例えば、:

class Custom(Model):

    __implementation__ = JavaScript(" <JS code here> ")

外部資源を提供する

Bokehでカスタムモデルを実現する一部としては,第三者JavascriptライブラリやCSSリソースが必要となる可能性がある.Bokehサポートは、Pythonクラス属性を介した外部リソースの提供をサポートします。 __javascript__ そして __css__ 模型をカスタマイズする。

外部リソースを含むURLパスにより、BokehはHTMLファイルヘッダにリソースを追加し、Javascriptライブラリをグローバル名前空間で利用可能にし、カスタムCSSスタイルを適用することになります。

一例は,以下を含むJSとCSSファイルである. KaTeX (LaTeXをサポートするJavascriptベースのレイアウトライブラリ)を作成するために LatexLabel モデルをカスタマイズする。

class LatexLabel(Label):
    """A subclass of the Bokeh built-in `Label` that supports rendering
    LaTeX using the KaTeX typesetting library.
    """
    __javascript__ = "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.js"
    __css__ = "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css"
    __implementation__ = """
    # do something here
    """

完全な実装および結果出力を表示するために、以下の拡張ライブラリのLaTeXの例を参照してください。

Bokeh Serverとの統合

カスタマイズされたユーザを、特別な作業や修正を必要とせずにBokehサーバと統合することができます。独立文書に対しては,JavaScript実現が自動的に提示されたアプリケーションに含まれる.また,すべての内蔵モデルに対するBokehモデル属性の標準同期は,カスタマイズユーザ拡張に対しても透過的である.

実例.

ここで私たちは参考のためにいくつかの完全な例を提示する。本節の情報は,カスタム拡張を作成する誰にとっても有用な出発点であることが望ましい.しかし、拡張を作ることは少し高度なテーマだ。多くの場合研究が必要です bokehjs/src/lib/models それがそうです。

専門化軸ポタポタ

サブクラスはBokehモデルを内蔵し,その行動を自己定義するために軸滴答に用いられる.

新しいカスタマイズツールです

描画キャンバス上に描画できる新しいツールを作ります

JavaScriptライブラリを包装する

Bokehカスタム拡張を使用してパッケージ化することにより、Pythonを第三者JavaScriptライブラリに接続します。

LaTeXタグの作成

LaTeXを提示するために第三者JavaScriptライブラリを含む。

カスタム·ウィジェットの追加

拡張ウィジェットには第三者JavaScriptライブラリが含まれる.

プリセット拡張モジュール

これまで、私たちは簡単で典型的な内部接続拡張について議論してきた。これらはBokehの一時的な追加には良いが,このような深刻な開発はすぐにかなり単調になる.例えば、いくつかのプロファイルの暗黙的な性質のため、IDEで拡張されたタイプのスクリプトやJavaScriptファイルを書くことで、このようなIDEの機能を十分に利用することはできません。 package.json あるいは…。 tsconfig.json それがそうです。これは、Bokeh拡張の別の方法を使用することによって解決することができ、Bokeh拡張は予め構築された拡張である。

To create a pre-built extension, one can use the bokeh init command, which creates all the necessary files, including bokeh.ext.json, package.json and tsconfig.json, and possibly others. Additionally, using bokeh init --interactive allows us to create and customize an extension step by step. Later, such an extension can be built with bokeh build command. This runs npm install if necessary, compiles TypeScript files, transpiles JavaScript files, resolves modules, and links them together in distributable bundles. Compilation products are cached for improved performance. If this causes issues, one can rebuild an extension from scratch by using the bokeh build --rebuild command.