BokehJS#
BokehJS 是一个客户端库,允许您创建交互式图表和应用程序。它负责绘图、渲染和事件处理。Bokeh Python 库(以及其他语言的库,如 R、Scala 和 Julia)提供了与 BokehJS 的便捷高级交互,因此您无需担心 JavaScript 或 Web 开发。
然而,BokehJS 也有自己的 API,允许你直接使用 BokehJS 进行纯 JavaScript 开发。此外,自定义扩展 通常需要与 BokehJS 直接交互。
警告
BokehJS API 仍在开发中,未来版本可能会有所变化。
获取BokehJS#
BokehJS 可以通过 CDN 和 npm
获取。更多详情请参阅 安装独立版 BokehJS 部分,位于 安装详情 页面。
低级模型#
通常,用于绘图和应用程序的低级模型(如指南、符号、小部件)与Bokeh Python模型完全匹配。因此,参考指南是BokehJS模型的主要参考,尽管它主要关注Python。
尽管Python库是按层次结构组织的,但JavaScript模型都位于一个扁平的Bokeh
模块中。通常,任何Python的ClassName
在JavaScript中都可以作为Bokeh.ClassName
使用。有关JavaScript模型的完整列表,请参见bokehjs/src/lib/api/models.ts。
在JavaScript中创建模型时,创建一个包含所有关键字参数的JavaScript对象,这些参数将传递给Python对象初始化器。以下是如何在两种语言中初始化Range1d模型的示例:
Python
xdr = Range1d(start=-0.5, end=20.5)
JavaScript
const xdr = new Bokeh.Range1d({ start: -0.5, end: 20.5 });
这种模式在所有类似的情况下都适用。一旦你创建了一个Bokeh模型,你可以在两种语言中以完全相同的方式设置其属性。例如,xdr.end = 30
在Python和JavaScript中将Range1d模型上的end
值设置为30。
下面是一个从头开始创建带有轴、网格和线条符号的图表示例。与examples/models中的示例进行比较,你会发现Python和JavaScript中的代码在这个级别上几乎相同:
// create some data and a ColumnDataSource
const x = Bokeh.LinAlg.linspace(-0.5, 20.5, 10);
const y = x.map(function (v) { return v * 0.5 + 3.0; });
const source = new Bokeh.ColumnDataSource({ data: { x: x, y: y } });
// create some ranges for the plot
const xdr = new Bokeh.Range1d({ start: -0.5, end: 20.5 });
const ydr = new Bokeh.Range1d({ start: -0.5, end: 20.5 });
// make the plot
const plot = new Bokeh.Plot({
title: "BokehJS Plot",
x_range: xdr,
y_range: ydr,
width: 400,
height: 400,
background_fill_color: "#F2F2F7"
});
// add axes to the plot
const xaxis = new Bokeh.LinearAxis({ axis_line_color: null });
const yaxis = new Bokeh.LinearAxis({ axis_line_color: null });
plot.add_layout(xaxis, "below");
plot.add_layout(yaxis, "left");
// add grids to the plot
const xgrid = new Bokeh.Grid({ ticker: xaxis.ticker, dimension: 0 });
const ygrid = new Bokeh.Grid({ ticker: yaxis.ticker, dimension: 1 });
plot.add_layout(xgrid);
plot.add_layout(ygrid);
// add a Line glyph
const 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);
上面的代码生成以下图表:
接口#
与Python Bokeh库类似,BokehJS提供了各种高级接口。这些接口允许您与低级模型对象进行交互和组合。高级接口包括Bokeh.Plotting
和Bokeh.Charts
。
注意
从版本 0.12.2
开始,这些 API 构成了 bokeh-api.js
文件中的 BokehJS API。除了 bokeh.js
文件外,您还需要导入此文件以启用这些 API。
Bokeh.Plotting
#
JavaScript 的 Bokeh.Plotting
API 是 Python 的 bokeh.plotting 接口的移植版本。因此,用户指南中的 基本绘图 部分除了这里提供的材料外,也可以作为一个有用的参考。
下面的JavaScript示例与examples/basic/scatters/color_scatter.py中的Python代码非常相似:
const plt = Bokeh.Plotting;
// set up some data
const M = 100;
const xx = [];
const yy = [];
const colors = [];
const radii = [];
for (let y = 0; y <= M; y += 4) {
for (let x = 0; x <= M; x += 4) {
xx.push(x);
yy.push(y);
colors.push(plt.color([50+2*x, 30+2*y, 150]));
radii.push(Math.random() * 1.5);
}
}
// create a data source
const source = new Bokeh.ColumnDataSource({
data: { x: xx, y: yy, radius: radii, colors: colors }
});
// make the plot and add some tools
const tools = "pan,crosshair,wheel_zoom,box_zoom,reset,save";
const p = plt.figure({ title: "Colorful Scatter", tools: tools });
// call the circle glyph method to add some circle glyphs
const circles = p.circle({ field: "x" }, { field: "y" }, {field: "radius"}, {
source: source,
fill_color: { field: "colors" },
fill_alpha: 0.6,
line_color: null,
});
// show the plot
plt.show(p);
上面的代码生成以下图表:
Bokeh.Charts
#
JavaScript 的 Bokeh.Charts
API 是一个高级图表接口,它是 BokehJS 独有的。该 API 支持两种高级图表:pie
和 bar
。
Bokeh.Charts.pie
#
以下内容让你可以使用Bokeh.Charts.pie
创建基本的饼图:
Bokeh.Charts.pie(data, { options })
其中 data
是一个包含 labels
和
values
键的 JavaScript 对象,而 options
是一个可以包含
以下任意可选键的对象:
width
:number — 图表宽度,单位为像素
height
:number — 图表高度,单位为像素
inner_radius
:number — 楔形的内半径,单位为像素
outer_radius
:number — 楔形外半径,单位为像素
start_angle
:number — 楔形的起始角度,以弧度表示
end_angle
:number — 楔形的结束角度,以弧度表示
center
:[number, number] —
(x, y)
饼图中心的位置,以像素为单位palette
:调色板 | 数组<颜色> — 一个命名的调色板或颜色列表,用于将值映射为颜色
slice_labels
:“labels” | “values” | “percentages” — 工具提示应显示的内容
默认情况下,使用Bokeh.Charts.pie
创建的图表会自动添加工具提示和悬停策略。以下是一个pie
图表的示例及其生成的图表:
const plt = Bokeh.Plotting;
const pie_data = {
labels: ['Work', 'Eat', 'Commute', 'Sport', 'Watch TV', 'Sleep'],
values: [8, 2, 2, 4, 0, 8],
};
const p1 = Bokeh.Charts.pie(pie_data);
const p2 = Bokeh.Charts.pie(pie_data, {
inner_radius: 0.2,
start_angle: Math.PI / 2
});
const p3 = Bokeh.Charts.pie(pie_data, {
inner_radius: 0.2,
start_angle: Math.PI / 6,
end_angle: 5 * Math.PI / 6
});
const p4 = Bokeh.Charts.pie(pie_data, {
inner_radius: 0.2,
palette: "Oranges9",
slice_labels: "percentages"
});
// add the plot to a document and display it
const doc = new Bokeh.Document();
doc.add_root(plt.gridplot(
[[p1, p2], [p3, p4]],
{width: 250, height: 250}));
Bokeh.embed.add_document_standalone(doc, document.currentScript.parentElement);
上面的代码生成以下图表:
Bokeh.Charts.bar
#
以下内容允许您使用Bokeh.Charts.bar
创建基本的条形图:
Bokeh.Charts.bar(data, { options })
其中 data
是一个数组,其条目代表数据表的行。
第一行应包含列标题。以下是一些不同地区不同年份的销售数据示例:
const data = [
['Region', 'Year', 'Sales'],
['East', 2015, 23000 ],
['East', 2016, 35000 ],
['West', 2015, 16000 ],
['West', 2016, 34000 ],
['North', 2016, 12000 ],
];
类似于pie
图表,options
参数是一个对象,可以包含以下任意可选键:
width
:number — 图表宽度,单位为像素
height
:number — 图表高度,单位为像素
stacked
:boolean — 是否应将条形堆叠
orientation
:“horizontal” | “vertical” — 条形图的方向
bar_width
:number — 每个条的宽度,单位为像素
palette
:调色板 | 数组<颜色> — 一个命名的调色板或颜色列表,用于将值映射为颜色
axis_number_format
:string — 用于轴刻度的格式字符串
默认情况下,使用Bokeh.Charts.bar
创建的图表会自动添加工具提示和悬停策略。以下是一个bar
图表的示例及其生成的图表:
const plt = Bokeh.Plotting;
const bar_data = [
['City', '2010 Population', '2000 Population'],
['NYC', 8175000, 8008000],
['LA', 3792000, 3694000],
['Chicago', 2695000, 2896000],
['Houston', 2099000, 1953000],
['Philadelphia', 1526000, 1517000],
];
const p1 = Bokeh.Charts.bar(bar_data, {
axis_number_format: "0.[00]a"
});
const p2 = Bokeh.Charts.bar(bar_data, {
axis_number_format: "0.[00]a",
stacked: true
});
const p3 = Bokeh.Charts.bar(bar_data, {
axis_number_format: "0.[00]a",
orientation: "vertical"
});
const p4 = Bokeh.Charts.bar(bar_data, {
axis_number_format: "0.[00]a",
orientation: "vertical",
stacked: true
});
plt.show(plt.gridplot([[p1, p2], [p3, p4]], {width: 350, height: 350}));
上面的代码生成以下图表:
最小示例#
以下基本示例展示了如何导入库以及创建和修改图表。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Complete Example</title>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-3.6.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.6.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.6.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.6.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.6.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-api-3.6.2.min.js"></script>
<script>
//The order of CSS and JS imports above is important.
</script>
<script>
// create a data source to hold data
const source = new Bokeh.ColumnDataSource({
data: { x: [], y: [] }
});
// make a plot with some tools
const plot = Bokeh.Plotting.figure({
title: 'Example of random data',
tools: "pan,wheel_zoom,box_zoom,reset,save",
height: 300,
width: 300
});
// add a line with data from the source
plot.line({ field: "x" }, { field: "y" }, {
source: source,
line_width: 2
});
// show the plot, appending it to the end of the current section
Bokeh.Plotting.show(plot);
function addPoint() {
// add data --- all fields must be the same length.
source.data.x.push(Math.random())
source.data.y.push(Math.random())
// update the data source with local changes
source.change.emit()
}
const addDataButton = document.createElement("Button");
addDataButton.appendChild(document.createTextNode("Some data."));
document.currentScript.parentElement.appendChild(addDataButton);
addDataButton.addEventListener("click", addPoint);
addPoint();
addPoint();
</script>
</head>
<body>
</body>
</html>
上面的代码生成以下图表: