小部件和 DOM 元素#

小部件是交互式控制和显示元素,可以添加到 Bokeh 文档中,为可视化提供前端用户界面。小部件可以直接添加到文档根目录,也可以嵌套在布局中。

Bokeh 的小部件提供了一系列交互式功能,您可以使用这些功能来驱动新的计算、更新绘图以及连接到其他编程功能。

Bokeh 提供了一组简单的默认小部件集。您可以创建自己的自定义小部件,或者通过创建自定义扩展来封装不同的第三方小部件库,如自定义扩展中所述。

小部件交互性#

虽然有些小部件仅用于显示数据,但另一些小部件可用于交互式地操作可视化中的数据和对象属性。

Bokeh 使用回调来处理这些交互。回调有两种类型

使用哪种回调取决于您是否正在使用Bokeh 服务器或生成独立的 HTML 输出

  • 如果您想在独立 HTML 文档中使用小部件与 Bokeh 对象进行交互,则浏览器需要处理所有交互。因此,您只能使用JavaScript 回调。您可以编写自己的 Javascript 代码,或者使用 Bokeh 预定义的 Python 便利功能,例如js_link函数或SetValue对象,它们会为您生成必要的 JavaScript 代码。

  • 如果您想将小部件与 Bokeh 服务器结合使用,服务器可以处理一些交互。这使您可以使用用 Python 编写的回调。此外,由于可视化本身是在浏览器中显示的,因此您仍然可以使用JavaScript 回调

小部件工具提示#

您可以将工具提示附加到小部件。这可能有助于提供有关小部件用途或用法的其他信息,例如。

将鼠标悬停在“选择值”旁边的问号图标上以查看工具提示。

有关向小部件添加工具提示的更多信息,请参阅支持工具提示的 UI 元素

Bokeh 的内置小部件#

以下各节是 Bokeh 中所有可用小部件的示例。许多示例使用 JavaScript console.log 函数生成打印输出。您可以在浏览器的 JavaScript 控制台日志中看到此输出。

AutocompleteInput#

AutocompleteInput 小部件是一个通用的文本输入小部件,它使用可能的输入列表在键入时提供自动完成功能。

search_strategy 属性的默认值为 "starts_with",它将与可能的输入项的开头进行匹配。将 search_strategy 更改为 "includes" 意味着将显示与可能的输入项的任何子字符串匹配的结果

from bokeh.io import show
from bokeh.models import AutocompleteInput
from bokeh.sampledata.world_cities import data

completion_list = data["name"].tolist()

auto_complete_input =  AutocompleteInput(title="Enter a city:", completions=completion_list, search_strategy="includes")

show(auto_complete_input)

有关按钮的更多信息,请参见 AutocompleteInput 的参考指南条目。

Button#

Bokeh 提供了一个简单的 Button

from bokeh.io import show
from bokeh.models import Button, CustomJS

button = Button(label="Foo", button_type="success")
button.js_on_event("button_click", CustomJS(code="console.log('button: click!', this.toString())"))

show(button)

使用按钮的 button_type 属性来更改按钮的样式。有关可能的值,请参阅 button_type

您可以选择通过将 Bokeh 的图标对象之一传递给按钮的 icon 参数,向按钮添加图标

from bokeh.io import show
from bokeh.models import BuiltinIcon, Button, SetValue

icon = BuiltinIcon("settings", size="1.2em", color="white")
button = Button(label="Foo", icon=icon, button_type="primary")
button.js_on_event("button_click", SetValue(button, "label", "Bar"))

show(button)

Bokeh 支持按钮上的以下类型的图标

有关按钮的更多信息,请参见 Button 的参考指南条目。

CheckboxButtonGroup#

Bokeh 还提供了一个复选框按钮组,可以同时选择多个选项

from bokeh.io import show
from bokeh.models import CheckboxButtonGroup, CustomJS

LABELS = ["Option 1", "Option 2", "Option 3"]

checkbox_button_group = CheckboxButtonGroup(labels=LABELS, active=[0, 1])
checkbox_button_group.js_on_event("button_click", CustomJS(args=dict(btn=checkbox_button_group), code="""
    console.log('checkbox_button_group: active=' + btn.active, this.toString())
"""))

show(checkbox_button_group)

更多信息请参见 CheckboxButtonGroup 的参考指南条目。

CheckboxGroup#

一个标准复选框

from bokeh.io import show
from bokeh.models import CheckboxGroup, CustomJS

LABELS = ["Option 1", "Option 2", "Option 3"]

checkbox_group = CheckboxGroup(labels=LABELS, active=[0, 1])
checkbox_group.js_on_change('active', CustomJS(code="""
    console.log('checkbox_group: active=' + this.active, this.toString())
"""))

show(checkbox_group)

更多信息请参见 CheckboxGroup 的参考指南条目。

ColorPicker#

一个允许用户指定 RGB 颜色值的小部件。

from bokeh.layouts import column
from bokeh.models import ColorPicker
from bokeh.plotting import figure, show

plot = figure(x_range=(0, 1), y_range=(0, 1), width=350, height=350)
line = plot.line(x=(0,1), y=(0,1), color="black", line_width=4)

picker = ColorPicker(title="Line Color")
picker.js_link('color', line.glyph, 'line_color')

show(column(plot, picker))

更多信息请参见 ColorPicker 的参考指南条目。

DataCube#

Bokeh 提供了一个基于数据立方体的小部件,能够聚合层级数据。请注意,由于数据立方体是使用数据源对象配置的,因此任何共享此数据源的绘图都将自动在绘图和表格之间链接选择(即使在静态 HTML 文档中也是如此)。

from bokeh.io import show
from bokeh.models import (ColumnDataSource, DataCube, GroupingInfo,
                          StringFormatter, SumAggregator, TableColumn)

source = ColumnDataSource(data=dict(
    d0=['A', 'E', 'E', 'E', 'J', 'L', 'M'],
    d1=['B', 'D', 'D', 'H', 'K', 'L', 'N'],
    d2=['C', 'F', 'G', 'H', 'K', 'L', 'O'],
    px=[10, 20, 30, 40, 50, 60, 70],
))

target = ColumnDataSource(data=dict(row_indices=[], labels=[]))

formatter = StringFormatter(font_style='bold')

columns = [
    TableColumn(field='d2', title='Name', width=80, sortable=False, formatter=formatter),
    TableColumn(field='px', title='Price', width=40, sortable=False),
]

grouping = [
    GroupingInfo(getter='d0', aggregators=[SumAggregator(field_='px')]),
    GroupingInfo(getter='d1', aggregators=[SumAggregator(field_='px')]),
]

cube = DataCube(source=source, columns=columns, grouping=grouping, target=target)

show(cube)

更多信息请参见 DataTable 的参考指南条目。

DataTable#

Bokeh 提供了一个复杂的数据表格小部件。请注意,由于表格是使用数据源对象配置的,因此任何共享此数据源的绘图都将自动在绘图和表格之间链接选择(即使在静态 HTML 文档中也是如此)。

from datetime import date
from random import randint

from bokeh.io import show
from bokeh.models import ColumnDataSource, DataTable, DateFormatter, TableColumn

data = dict(
        dates=[date(2014, 3, i+1) for i in range(10)],
        downloads=[randint(0, 100) for i in range(10)],
    )
source = ColumnDataSource(data)

columns = [
        TableColumn(field="dates", title="Date", formatter=DateFormatter()),
        TableColumn(field="downloads", title="Downloads"),
    ]
data_table = DataTable(source=source, columns=columns, width=400, height=280)

show(data_table)

更多信息请参见 DataTable 的参考指南条目。

DatePicker#

一个允许用户指定日期值的小部件。

from bokeh.io import show
from bokeh.models import CustomJS, DatePicker

date_picker = DatePicker(
    title="Select date",
    value="2019-09-20",
    min_date="2019-08-01",
    max_date="2019-10-30",
)
date_picker.js_on_change("value", CustomJS(code="""
    console.log("date_picker: value=" + this.value, this.toString())
"""))

show(date_picker)

更多信息请参见 DatePicker 的参考指南条目。

DateRangePicker#

一个允许用户指定两个日期值之间的范围的小部件。

from bokeh.io import show
from bokeh.models import CustomJS, DateRangePicker

date_range_picker = DateRangePicker(
    title="Select date range",
    value=("2019-09-20", "2019-10-15"),
    min_date="2019-08-01",
    max_date="2019-10-30",
    width=400,
)
date_range_picker.js_on_change("value", CustomJS(code="""
    console.log("date_range_picker: value=" + this.value, this.toString())
"""))

show(date_range_picker)

更多信息请参见 DateRangePicker 的参考指南条目。

MultipleDatePicker#

一个允许用户指定多个日期值的小部件。

from bokeh.io import show
from bokeh.models import CustomJS, MultipleDatePicker

multiple_date_picker = MultipleDatePicker(
    title="Select dates",
    value=["2019-09-20", "2019-09-21", "2019-10-15"],
    min_date="2019-08-01",
    max_date="2019-10-30",
    width=400,
)
multiple_date_picker.js_on_change("value", CustomJS(code="""
    console.log("multiple_date_picker: value=" + this.value, this.toString())
"""))

show(multiple_date_picker)

更多信息请参见 MultipleDatePicker 的参考指南条目。

DatetimePicker#

一个允许用户指定日期和时间值的小部件。

from bokeh.io import show
from bokeh.models import CustomJS, DatetimePicker

datetime_picker = DatetimePicker(
    title="Select date and time",
    value="2019-09-20T12:37:51",
    min_date="2019-08-01T09:00:00",
    max_date="2019-10-30T18:00:00",
)
datetime_picker.js_on_change("value", CustomJS(code="""
    console.log("datetime_picker: value=" + this.value, this.toString())
"""))

show(datetime_picker)

更多信息请参见 DatetimePicker 的参考指南条目。

DatetimeRangePicker#

一个允许用户指定两个日期和时间值之间的范围的小部件。

from bokeh.io import show
from bokeh.models import CustomJS, DatetimeRangePicker

datetime_range_picker = DatetimeRangePicker(
    title="Select date and time range",
    value=("2019-09-20T12:37:51", "2019-10-15T17:59:18"),
    min_date="2019-08-01T09:00:00",
    max_date="2019-10-30T18:00:00",
    width=400,
)
datetime_range_picker.js_on_change("value", CustomJS(code="""
    console.log("datetime_range_picker: value=" + this.value, this.toString())
"""))

show(datetime_range_picker)

更多信息请参见 DatetimeRangePicker 的参考指南条目。

MultipleDatetimePicker#

一个允许用户指定多个日期和时间值的小部件。

from bokeh.io import show
from bokeh.models import CustomJS, MultipleDatetimePicker

multiple_datetime_picker = MultipleDatetimePicker(
    title="Select dates and times",
    value=[
        "2019-09-20T12:59:31",
        "2019-09-21T13:31:00",
        "2019-10-15T14:00:18",
    ],
    min_date="2019-08-01T09:00:00",
    max_date="2019-10-30T18:00:00",
    width=400,
)
multiple_datetime_picker.js_on_change("value", CustomJS(code="""
    console.log("multiple_datetime_picker: value=" + this.value, this.toString())
"""))

show(multiple_datetime_picker)

更多信息请参见 MultipleDatetimePicker 的参考指南条目。

TimePicker#

一个允许用户指定时间值的小部件。

from bokeh.io import show
from bokeh.models import CustomJS, TimePicker

time_picker = TimePicker(title="Select time", value="12:59:31", min_time="09:00:00", max_time="18:00:00")
time_picker.js_on_change("value", CustomJS(code="""
    console.log("time_picker: value=" + this.value, this.toString())
"""))

show(time_picker)

更多信息请参见 TimePicker 的参考指南条目。

DateRangeSlider#

Bokeh 日期范围滑块可以使用 startend 日期值、以天为单位的 step 大小、初始 valuetitle 进行配置

from datetime import date

from bokeh.io import show
from bokeh.models import CustomJS, DateRangeSlider

date_range_slider = DateRangeSlider(value=(date(2016, 1, 1), date(2016, 12, 31)),
                                    start=date(2015, 1, 1), end=date(2017, 12, 31))
date_range_slider.js_on_change("value", CustomJS(code="""
    console.log('date_range_slider: value=' + this.value, this.toString())
"""))

show(date_range_slider)

更多信息请参见 DateRangeSlider 的参考指南条目。

DateSlider#

Bokeh 日期滑块可以使用 startend 日期值、以天为单位的 step 大小、初始 valuetitle 进行配置

from datetime import date

from bokeh.io import show
from bokeh.models import CustomJS, DateSlider

date_slider = DateSlider(value=date(2016, 1, 1),
                         start=date(2015, 1, 1),
                         end=date(2017, 12, 31))
date_slider.js_on_change("value", CustomJS(code="""
    console.log('date_slider: value=' + this.value, this.toString())
"""))

show(date_slider)

更多信息请参见 DateSlider 的参考指南条目。

DatetimeRangeSlider#

Bokeh 日期时间范围滑块与日期范围滑块相同,只是它使用包含小时、分钟和秒的日期时间

from datetime import datetime

from bokeh.io import show
from bokeh.models import CustomJS, DatetimeRangeSlider

datetime_range_slider = DatetimeRangeSlider(value=(datetime(2022, 3, 8, 12), datetime(2022, 3, 25, 18)),
                                            start=datetime(2022, 3, 1), end=datetime(2022, 3, 31))
datetime_range_slider.js_on_change("value", CustomJS(code="""
    console.log('datetime_range_slider: value=' + this.value, this.toString())
"""))

show(datetime_range_slider)

更多信息请参见 DatetimeRangeSlider 的参考指南条目。

Div#

一个用于显示文本的小部件,可以在 <div> 标签中支持 HTML

from bokeh.io import show
from bokeh.models import Div

div = Div(text="""Your <a href="https://en.wikipedia.org/wiki/HTML">HTML</a>-supported text is initialized with the <b>text</b> argument.  The
remaining div arguments are <b>width</b> and <b>height</b>. For this example, those values
are <i>200</i> and <i>100</i>, respectively.""",
width=200, height=100)

show(div)

更多信息请参见 Div 的参考指南条目。

FileInput#

一个允许用户选择文件并存储其内容的小部件。

from bokeh.io import show
from bokeh.models import FileInput

file_input = FileInput()

show(file_input)

更多信息请参见 FileInput 的参考指南条目。

HelpButton#

一个提供帮助符号的小部件,当鼠标悬停或单击时,会在 Tooltip 中显示其他文本。

帮助按钮的工具提示的默认行为如下

  • 如果鼠标悬停在帮助按钮上,则工具提示会在鼠标移开后自动关闭。

  • 如果单击帮助按钮,则工具提示将是持久的。用户需要单击工具提示右上角的“x”符号才能将其关闭。

from bokeh.io import show
from bokeh.models import HelpButton, Tooltip
from bokeh.models.dom import HTML

help_button = HelpButton(tooltip=Tooltip(content=HTML("""
This is a tooltip with additional information.<br />
It can use <b>HTML tags</b> like <a href="https://bokeh.org.cn">links</a>!
"""), position="right"))

show(help_button)

更多信息请参见 HelpButton 的参考指南条目。

MultiChoice#

一个多选小部件,用于在紧凑的水平布局中呈现多个可用选项

from bokeh.io import show
from bokeh.models import CustomJS, MultiChoice

OPTIONS = ["foo", "bar", "baz", "quux"]

multi_choice = MultiChoice(value=["foo", "baz"], options=OPTIONS)
multi_choice.js_on_change("value", CustomJS(code="""
    console.log('multi_choice: value=' + this.value, this.toString())
"""))

show(multi_choice)

更多信息请参见 MultiChoice 的参考指南条目。

MultiSelect#

一个多选小部件,用于在垂直列表中呈现多个可用选项

from bokeh.io import show
from bokeh.models import CustomJS, MultiSelect

OPTIONS = [("1", "foo"), ("2", "bar"), ("3", "baz"), ("4", "quux")]

multi_select = MultiSelect(value=["1", "2"], options=OPTIONS)
multi_select.js_on_change("value", CustomJS(code="""
    console.log('multi_select: value=' + this.value, this.toString())
"""))

show(multi_select)

更多信息请参见 MultiSelect 的参考指南条目。

NumericInput#

一个允许用户输入数值的小部件。

from bokeh.io import show
from bokeh.models import NumericInput

numeric_input = NumericInput(value=1, low=1, high=10, title="Enter a number between 1 and 10:")

show(numeric_input)

更多信息请参见 NumericInput 的参考指南条目。

Paragraph#

一个用于在 HTML <p> 标签中显示文本块的小部件

from bokeh.io import show
from bokeh.models import Paragraph

p = Paragraph(text="""Your text is initialized with the 'text' argument.  The
remaining Paragraph arguments are 'width' and 'height'. For this example, those values
are 200 and 100, respectively.""",
width=200, height=100)

show(p)

更多信息请参见 Paragraph 的参考指南条目。

PasswordInput#

一个模糊输入文本的文本输入框

from bokeh.io import show
from bokeh.models import CustomJS, PasswordInput

password_input = PasswordInput(placeholder="enter password...")
password_input.js_on_change("value", CustomJS(code="""
    console.log('password_input: value=' + this.value, this.toString())
"""))

show(password_input)

更多信息请参见 PasswordInput 的参考指南条目。

PreText#

一个用于在 HTML <pre> 标签中显示预格式化文本块的小部件

from bokeh.io import show
from bokeh.models import PreText

pre = PreText(text="""Your text is initialized with the 'text' argument.

The remaining Paragraph arguments are 'width' and 'height'. For this example,
those values are 500 and 100, respectively.""",
width=500, height=100)

show(pre)

更多信息请参见 PreText 的参考指南条目。

Progress#

一个指示器小部件,允许可视化任务、计算等的进度(确定模式)或允许指示正在完成的工作(如果无法确定工作量)(不确定模式)

from bokeh.io import show
from bokeh.layouts import row
from bokeh.models import Button, CustomJS, Progress

progress = Progress(value=0, min=0, max=179, label="Processing item @{index} of @{total} (@{percent}%)", width=300)

button = Button(label="Start computation")
button.js_on_click(CustomJS(
    args=dict(progress=progress, button=button),
    code="""
function delay(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms))
}
export default async ({progress, button}) => {
    button.disabled = true
    progress.value = 0
    try {
        while (!progress.has_finished) {
            const ms = Math.random()*100
            await delay(ms)
            progress.increment(1)
        }
    } finally {
        button.disabled = false
    }
}
"""))

show(row([button, progress]))

更多信息请参见 Progress 的参考指南条目。

RadioButtonGroup#

一个单选按钮组一次最多只能选择一个按钮

from bokeh.io import show
from bokeh.models import CustomJS, RadioButtonGroup

LABELS = ["Option 1", "Option 2", "Option 3"]

radio_button_group = RadioButtonGroup(labels=LABELS, active=0)
radio_button_group.js_on_event("button_click", CustomJS(args=dict(btn=radio_button_group), code="""
    console.log('radio_button_group: active=' + btn.active, this.toString())
"""))

show(radio_button_group)

更多信息请参见 RadioButtonGroup 的参考指南条目。

RadioGroup#

一个单选组使用标准的单选按钮外观

from bokeh.io import show
from bokeh.models import CustomJS, RadioGroup

LABELS = ["Option 1", "Option 2", "Option 3"]

radio_group = RadioGroup(labels=LABELS, active=0)
radio_group.js_on_event('button_click', CustomJS(code="""
    console.log('radio_group: active=' + this.origin.active, this.toString())
"""))

show(radio_group)

更多信息请参见 RadioGroup 的参考指南条目。

RangeSlider#

Bokeh 范围滑块可以使用 startend 值、step 大小、初始 valuetitle 进行配置

from bokeh.io import show
from bokeh.models import CustomJS, RangeSlider

range_slider = RangeSlider(start=0, end=10, value=(1,9), step=.1, title="Stuff")
range_slider.js_on_change("value", CustomJS(code="""
    console.log('range_slider: value=' + this.value, this.toString())
"""))

show(range_slider)

更多信息请参见 RangeSlider 的参考指南条目。

Select#

一个单项选择小部件

from bokeh.io import show
from bokeh.models import CustomJS, Select

select = Select(title="Option:", value="foo", options=["foo", "bar", "baz", "quux"])
select.js_on_change("value", CustomJS(code="""
    console.log('select: value=' + this.value, this.toString())
"""))

show(select)

更多信息请参见 Select 的参考指南条目。

Slider#

Bokeh 滑块可以使用 startend 值、step 大小、初始 valuetitle 进行配置

from bokeh.io import show
from bokeh.models import CustomJS, Slider

slider = Slider(start=0, end=10, value=1, step=.1, title="Stuff")
slider.js_on_change("value", CustomJS(code="""
    console.log('slider: value=' + this.value, this.toString())
"""))

show(slider)

更多信息请参见 Slider 的参考指南条目。

Spinner#

一个数值微调器小部件

import numpy as np

from bokeh.layouts import column, row
from bokeh.models import Spinner
from bokeh.plotting import figure, show

x = np.random.rand(10)
y = np.random.rand(10)

p = figure(x_range=(0, 1), y_range=(0, 1))
points = p.scatter(x=x, y=y, size=4)

spinner = Spinner(title="Glyph size", low=1, high=40, step=0.5, value=4, width=80)
spinner.js_link('value', points.glyph, 'size')

show(row(column(spinner, width=100), p))

更多信息请参见 Spinner 的参考指南条目。

Switch#

一个开/关切换开关

from bokeh.io import show
from bokeh.models import CustomJS, Switch

switch = Switch(active=True)
switch.js_on_change("active", CustomJS(code="""
    console.log('switch: active=' + this.active, this.toString())
"""))
show(switch)

更多信息请参见 Switch 的参考指南条目。

Tabs#

选项卡窗格允许在可选择的选项卡中显示多个绘图或布局

from bokeh.models import TabPanel, Tabs, Tooltip
from bokeh.models.layouts import Row
from bokeh.plotting import figure, show

p1 = figure(width=300, height=300)
p1.scatter([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=20, color="navy", alpha=0.5)

p2 = figure(width=300, height=300)
p2.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=3, color="navy", alpha=0.5)

p3 = figure(width=300, height=300)
p3.scatter([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=20, color="navy", alpha=0.5)

p4 = figure(width=300, height=300)
p4.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=3, color="navy", alpha=0.5)

tabs0 = Tabs(tabs=[
    TabPanel(child=p1, title="circle"),
    TabPanel(child=p2, title="line"),
])

tabs1 = Tabs(tabs=[
    TabPanel(child=p1, title="circle", tooltip=Tooltip(content="This is the first tab.", position="bottom_center")),
    TabPanel(child=p2, title="line", tooltip=Tooltip(content="This is the second tab.", position="bottom_center")),
])

show(Row(tabs0, tabs1))

更多信息请参见 Tabs 的参考指南条目。

TextAreaInput#

一个用于从用户那里收集多行文本的小部件

from bokeh.io import show
from bokeh.models import CustomJS, TextAreaInput

text_area_input = TextAreaInput(value="default", rows=6, title="Label:")
text_area_input.js_on_change("value", CustomJS(code="""
    console.log('text_area_input: value=' + this.value, this.toString())
"""))

show(text_area_input)

更多信息请参见 TextAreaInput 的参考指南条目。

TextInput#

一个用于从用户那里收集一行文本的小部件

from bokeh.io import show
from bokeh.models import CustomJS, TextInput

text_input = TextInput(value="default", title="Label:")
text_input.js_on_change("value", CustomJS(code="""
    console.log('text_input: value=' + this.value, this.toString())
"""))

show(text_input)

更多信息请参见 TextInput 的参考指南条目。

Toggle#

切换按钮保持开/关状态

from bokeh.io import show
from bokeh.models import CustomJS, Toggle

toggle = Toggle(label="Foo", button_type="success")
toggle.js_on_event('button_click', CustomJS(args=dict(btn=toggle), code="""
    console.log('toggle: active=' + btn.active, this.toString())
"""))

show(toggle)

与标准Button小部件一样,切换按钮也可以使用Icon(例如BuiltinIconSVGIconTablerIcon)。

更多信息请参见 Toggle 的参考指南条目。