为了在浏览器中创建交互式绘图和应用程序,Bokeh有一个客户端库BokehJS,可以在浏览器中完成绘制、渲染和事件处理的所有工作。Bokeh Python库(以及R、Scala和Julia等其他语言的库)主要是一种在高层方便地与BokehJS交互的方法,而不需要显式地担心JavaScript或web开发。
但是,BokehJS有自己的API,可以直接使用BokehJS进行纯JavaScript开发。另外, 扩展Bokeh 定制模型通常也需要与BokehJS直接交互。
警告
bokehjsapi仍然被认为是实验性的,在未来的版本中可能会发生变化。
BokehJS通过CDN和 npm . 见 博克赫斯 剖面图 安装 有关详细信息,请参见第页。
npm
用于构建绘图和应用程序的低级模型(例如指南、字形和小部件等)通常与Bokeh Python模型完全匹配。因此 参考文献 虽然本文从基本的角度回答了bohjs的问题,但它是从bohjs的角度来回答问题的。
与Python库的分层组织不同,所有JavaScript模型都在一个平面中 Bokeh 模块。通常是任何 Python ClassName 可作为 Bokeh.ClassName 从JavaScript。JavaScript提供的模型的完整列表可以在 bokehjs/src/lib/api/models.ts .
Bokeh
ClassName
Bokeh.ClassName
从JavaScript创建模型时,将传递给Python对象初始值设定项的所有关键字参数都作为JavaScript对象传递。下面是如何创建 Range1d 模型。首先,在Python中:
xdr = Range1d(start=-0.5, end=20.5)
以及相应的JavaScript版本:
var xdr = new Bokeh.Range1d({ start: -0.5, end: 20.5 });
这种模式大体上是这样的。一旦创建,Bokeh模型属性在两种语言中的设置方式完全相同。设置 end 值设置为30 Range1d 从上面,使用 xdr.end = 30 在Python或JavaScript中。
end
xdr.end = 30
作为示例,下面是一个从零开始创建带有轴、栅格和线轮廓的打印的示例。与中的示例比较 examples/models 将显示在这个级别从Python到JavaScript的转换几乎是一对一的:
// 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 } }); // create some ranges for the plot var xdr = new Bokeh.Range1d({ start: -0.5, end: 20.5 }); var ydr = new Bokeh.Range1d({ start: -0.5, end: 20.5 }); // make the plot var plot = new Bokeh.Plot({ title: "BokehJS Plot", x_range: xdr, y_range: ydr, plot_width: 400, plot_height: 400, background_fill_color: "#F2F2F7" }); // 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 grids to the plot var xgrid = new Bokeh.Grid({ ticker: xaxis.ticker, dimension: 0 }); var ygrid = new Bokeh.Grid({ ticker: yaxis.ticker, dimension: 1 }); plot.add_layout(xgrid); plot.add_layout(ygrid); // 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);
The code above generates the following plot:
与Python Bokeh库类似,BokehJS提供了各种高级接口,用于与低级模型对象进行交互和组合。这些高级接口目前包括 Bokeh.Plotting 和 Bokeh.Charts .
Bokeh.Plotting
Bokeh.Charts
注解
至于 0.12.2 下面描述的API被拆分为BokehJS API,在 bokeh-api.js 文件,除了 bokeh.js .
0.12.2
bokeh-api.js
bokeh.js
JavaScript Bokeh.Plotting API是Python的一个端口 bokeh.plotting 接口。因此,在 使用基本图示符打印 这里可以作为用户指南的补充资料。
bokeh.plotting
下面是一个与Python示例非常相似的示例 examples/plotting/file/color_scatter.py :
var plt = Bokeh.Plotting; // set up some data var M = 100; var xx = []; var yy = []; var colors = []; var radii = []; for (var y = 0; y <= M; y += 4) { for (var 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() * 0.4 + 1.7) } } // create a data source var source = new Bokeh.ColumnDataSource({ data: { x: xx, y: yy, radius: radii, colors: colors } }); // make the plot and add some tools var tools = "pan,crosshair,wheel_zoom,box_zoom,reset,save"; var p = plt.figure({ title: "Colorful Scatter", tools: tools }); // call the circle glyph method to add some circle glyphs var circles = p.circle({ field: "x" }, { field: "y" }, { source: source, radius: radii, fill_color: colors, fill_alpha: 0.6, line_color: null }); // show the plot plt.show(p);
JavaScript Bokeh.Charts API是BokehJS独有的用于图表的高级接口。目前支持两种高级图表: pie 和 bar .
pie
bar
Bokeh.Charts.pie
使用创建饼图的步骤 Bokeh.Charts.pie ,基本用法是:
Bokeh.Charts.pie(data, { options })
Where data is a JavaScript object that has labels and values keys, and options is an object that has any of the following optional keys:
data
labels
values
options
width
数 ---图表宽度(像素)
height
数 ---图表高度(像素)
inner_radius
数 ---楔形的内半径(像素)
outer_radius
数 ---外半径像素
start_angle
数 ---楔体的起始角度(弧度)
end_angle
数 ---楔体的结束角度(弧度)
center
[[数字,数字]] --- (x, y) 饼图中心的位置(以像素为单位)
(x, y)
palette
Palette | Array<Color> ---命名调色板,或颜色列表以对值进行颜色映射
slice_labels
“标签”|“值”|“百分比” ---工具提示应显示的内容
默认情况下,创建打印 Bokeh.Charts.pie 自动添加工具提示和悬停策略。下面是一些示例代码,它演示了 pie 函数,生成的绘图如下所示:
var plt = Bokeh.Plotting; var pie_data = { labels: ['Work', 'Eat', 'Commute', 'Sport', 'Watch TV', 'Sleep'], values: [8, 2, 2, 4, 0, 8], }; var p1 = Bokeh.Charts.pie(pie_data); var p2 = Bokeh.Charts.pie(pie_data, { inner_radius: 0.2, start_angle: Math.PI / 2 }); var p3 = Bokeh.Charts.pie(pie_data, { inner_radius: 0.2, start_angle: Math.PI / 6, end_angle: 5 * Math.PI / 6 }); var p4 = Bokeh.Charts.pie(pie_data, { inner_radius: 0.2, palette: "Oranges9", slice_labels: "percentages" }); // add the plot to a document and display it var doc = new Bokeh.Document(); doc.add_root(plt.gridplot( [[p1, p2], [p3, p4]], {plot_width:250, plot_height:250})); Bokeh.embed.add_document_standalone(doc, document.currentScript.parentElement);
Bokeh.Charts.bar
使用创建条形图 Bokeh.Charts.bar ,基本用法是:
Bokeh.Charts.bar(data, { options })
Where data is a JavaScript array that has as elements lists that are "rows" from a data table. The first "row" should contain the column headers. Here is an example that might represent sales data from different regions for different years:
var data = [ ['Region', 'Year', 'Sales'], ['East', 2015, 23000 ], ['East', 2016, 35000 ], ['West', 2015, 16000 ], ['West', 2016, 34000 ], ['North', 2016, 12000 ], ];
类似 pie , the options 可选键是具有以下任何参数的对象:
stacked
布尔 ---是否堆放钢筋
orientation
“水平”|“垂直” ---酒吧应该如何定位
bar_width
数 ---每个条的宽度(像素)
axis_number_format
一串 ---用于轴刻度的格式字符串
默认情况下,使用 Bokeh.Charts.bar 自动添加工具提示和悬停策略。下面是一些示例代码,它演示了 bar 函数,生成的绘图如下所示:
var plt = Bokeh.Plotting; var bar_data = [ ['City', '2010 Population', '2000 Population'], ['NYC', 8175000, 8008000], ['LA', 3792000, 3694000], ['Chicago', 2695000, 2896000], ['Houston', 2099000, 1953000], ['Philadelphia', 1526000, 1517000], ]; var p1 = Bokeh.Charts.bar(bar_data, { axis_number_format: "0.[00]a" }); var p2 = Bokeh.Charts.bar(bar_data, { axis_number_format: "0.[00]a", stacked: true }); var p3 = Bokeh.Charts.bar(bar_data, { axis_number_format: "0.[00]a", orientation: "vertical" }); var p4 = Bokeh.Charts.bar(bar_data, { axis_number_format: "0.[00]a", orientation: "vertical", stacked: true }); plt.show(plt.gridplot([[p1, p2], [p3, p4]], {plot_width:350, plot_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-2.2.2.min.js" integrity="sha384-JayppSWSRBsibIZqI8S4vAb1oFgLL0uhNvSn8cmArlOvYOwfFjYeyY5UWwJ+K0SU" crossorigin="anonymous"></script> <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.2.2.min.js" integrity="sha384-G0/Tv/Yy/zEPNsnW0Qif/FOsGesd+KIrKg/QLmvQmReuUW9qmSP7mAmr0VpiUNr3" crossorigin="anonymous"></script> <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.2.2.min.js" integrity="sha384-VLYHEbLQDk5G1+/4ALU0myoJPMEUsngWry2fzYorFOUmarjGRPLLURaeK/on6JqX" crossorigin="anonymous"></script> <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-api-2.2.2.min.js" integrity="sha384-EXPyJ4IEk/8c98M2Jzr73JbWF1pBJy55QazUgFTG0iIFmyTyKJk0wG8gD8Ag4zos" crossorigin="anonymous"></script> <script> //The order of CSS and JS imports above is important. </script> <script> // create a data source to hold data var source = new Bokeh.ColumnDataSource({ data: { x: [], y: [] } }); // make a plot with some tools var 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()) // notify the DataSource of "in-place" changes source.change.emit() } var addDataButton = document.createElement("Button"); addDataButton.appendChild(document.createTextNode("Add Some Data!!!")); document.currentScript.parentElement.appendChild(addDataButton); addDataButton.addEventListener("click", addPoint); addPoint(); addPoint(); </script> </head> <body> </body> </html>