Bokeh figure 完整指南:Python 交互式绘图的入口类与全部绘图方法
【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh
figure是 Bokeh 库中创建交互式绘图的核心工厂类:它继承自Plot模型,并自动为画布装配坐标轴、网格线和默认工具栏,同时暴露了一整套向量化 glyph 绘图方法。本文以官方 API 参考文档 figure.rst 为骨架,结合仓库源码逐一拆解其全部构造参数、绘图方法家族与底层实现原理,帮助你从"会用figure()"进阶到"理解figure的每一处设计"。
一、figure 是什么:一个自动化的 Plot 子类
从源码 src/bokeh/plotting/_figure.py 可以看到,figure类的定义是:
class figure(Plot, GlyphAPI): ''' Create a new figure for plotting. A subclass of |Plot| that simplifies plot creation with default axes, grids, tools, etc. '''它的设计目标非常明确:简化绘图流程。如果你直接使用底层Plot模型,需要手动创建DataRange1d、LinearAxis、Grid、Toolbar等一系列对象;而figure在__init__中通过 FigureOptions 解析全部关键字参数,自动完成五件事:
- 解析
x_range/y_range并创建对应的 Range 对象; - 根据
x_axis_type/y_axis_type选择 Scale(线性、对数、分类、日期等); - 创建坐标轴与网格(
process_axis_and_grid); - 解析
tools字符串并实例化工具对象; - 设置初始激活工具(
process_active_tools)。
figure还继承自GlyphAPI(见 src/bokeh/plotting/glyph_api.py),因此所有 glyph 绘图方法、堆叠方法与子坐标系统 API 都直接可用。在bokeh.plotting命名空间中,figure与show、output_file、ColumnDataSource等一同被导出(见 src/bokeh/plotting/init.py),是绝大多数 Bokeh 应用的起点:
from bokeh.plotting import figure, show, output_file output_file("plot.html") p = figure(title="My first plot") p.line([1, 2, 3, 4], [1, 4, 9, 16], line_width=2) show(p)二、figure 的全部构造参数详解
figure()除了接受所有Plot属性(如title、width、height、background_fill_color等)之外,还接受一组专属的FigureOptions(继承自BaseFigureOptions),它们在 src/bokeh/plotting/_figure.py 中定义。下表汇总了全部选项及其默认值:
| 参数 | 类型 | 默认值 | 作用 |
|---|---|---|---|
x_range | Range 实例 / 二元组 / 字符串序列 / Series / GroupBy | 自动创建DataRange1d | 定制 x 轴范围 |
y_range | 同上 | 自动创建DataRange1d | 定制 y 轴范围 |
x_axis_type | "auto"/"linear"/"log"/"datetime"/"timedelta"/"mercator"/None | "auto" | x 轴类型,None表示不创建坐标轴 |
y_axis_type | 同上 | "auto" | y 轴类型 |
x_axis_location | "above"/"below"/None | "below" | x 轴位置 |
y_axis_location | "left"/"right"/None | "left" | y 轴位置 |
x_axis_label | 字符串 /BaseText | "" | x 轴标签 |
y_axis_label | 字符串 /BaseText | "" | y 轴标签 |
x_minor_ticks | "auto"/ int | "auto" | x 轴主刻度间的小刻度数 |
y_minor_ticks | "auto"/ int | "auto" | y 轴主刻度间的小刻度数 |
tools | 字符串 / 工具对象序列 | "pan,wheel_zoom,auto_box_zoom,save,reset,help" | 初始工具集 |
tooltips | 字符串 /(field, format)元组列表 /Template | None | 配置悬停提示,自动创建HoverTool |
active_drag | "auto"/ 工具名 /Drag实例 /None | "auto" | 初始激活的拖拽工具 |
active_inspect | "auto"/ 工具名 /InspectTool或列表 /None | "auto" | 初始激活的检查工具 |
active_scroll | "auto"/ 工具名 /Scroll实例 /None | "auto" | 初始激活的滚轮工具 |
active_tap | "auto"/ 工具名 /Tap实例 /None | "auto" | 初始激活的点击工具 |
active_multi | "auto"/ 工具名 /GestureTool实例 /None | "auto" | 初始激活的多手势工具(如编辑工具、RangeTool) |
2.1 范围(Range)参数:x_range / y_range
RangeLike类型的定义(src/bokeh/plotting/_figure.py)决定了x_range/y_range的合法输入:
- 一个
Range模型实例(如Range1d、DataRange1d、FactorRange); (start, end)二元组,数字、日期时间或时间增量均可;- 字符串序列(自动转换为分类范围
FactorRange); - pandas
Series、ExtensionArray或GroupBy对象。
底层处理函数是 get_range:当传入字符串序列时返回FactorRange(factors=...);当传入长度为 2 的序列时返回Range1d(start=..., end=...);当传入 pandasGroupBy时,会按其分组键排序生成FactorRange。一个典型的分类坐标示例(参见 examples/basic/bars/basic.py):
fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'] p = figure(x_range=fruits, height=350, title="Fruit Counts") p.vbar(x=fruits, top=[5, 3, 4, 2, 4, 6], width=0.9)2.2 坐标轴类型:x_axis_type / y_axis_type
坐标轴类型的选择逻辑集中在 get_scale 与 _get_axis_class 两个函数中:
- 传入
"log"时使用LogScale+LogAxis(对数坐标); - 传入
"datetime"使用DatetimeAxis,"timedelta"使用TimedeltaAxis,"mercator"使用MercatorAxis(用于 Web 墨卡托投影地图); - 传入
None则不创建该方向的坐标轴与网格; - 默认
"auto"会根据范围类型智能推断:FactorRange使用CategoricalAxis,Range1d中若值为日期时间则使用DatetimeAxis,否则回退到LinearAxis。
坐标轴与网格的装配由 process_axis_and_grid 完成:它创建坐标轴实例、将Grid(dimension=dim, axis=axis)添加到画布中心,并按axis_location将坐标轴放入 plot 对应侧。注意小刻度数目的约束:若显式传入小于等于 1 的x_minor_ticks/y_minor_ticks会抛出ValueError;"auto"时对数轴取 10、线性轴取 5。
p = figure(x_axis_type="log", y_axis_type="log") # 双对数坐标 p = figure(x_axis_type="datetime") # 日期坐标轴 p = figure(x_axis_type=None) # 不显示 x 轴与网格2.3 工具与悬停提示:tools / tooltips / active_*
DEFAULT_TOOLS定义在 src/bokeh/plotting/_figure.py:
DEFAULT_TOOLS = "pan,wheel_zoom,auto_box_zoom,save,reset,help"工具字符串的解析在 process_tools_arg 中实现:字符串按逗号切分后通过Tool.from_string(tool)逐一实例化;也可以传入Tool对象列表与字符串的混合序列。特别地,tooltips参数的行为是:如果tools中已有HoverTool,则覆盖其tooltips属性;否则自动追加一个新的HoverTool(源码中通过for...else语法实现)。
active_drag、active_inspect、active_scroll、active_tap、active_multi五个参数由 process_active_tools 处理,支持"auto"、工具字符串名、或直接传入工具实例。例如:
p = figure(tools="pan,wheel_zoom,box_zoom,reset", active_drag="box_zoom", tooltips=[("x", "$x"), ("y", "$y"), ("value", "@y")])三、figure 的绘图方法大家族
figure对象的强大之处在于它内置了数十个向量化绘图方法。官方文档通过autoclass指令自动列出全部成员,下面按功能族分类梳理。
3.1 基础标记与散点:scatter 与 30+ 种 marker
scatter()是唯一可以通过 marker 类型参数化的散点方法,定义于 glyph_api.py。此外,每个 marker 形状都有独立方法,包括:
- 圆形系:
circle、circle_cross、circle_dot、circle_x、circle_y - 方形系:
square、square_cross、square_dot、square_pin、square_x - 三角系:
triangle、triangle_dot、triangle_pin、inverted_triangle - 菱形系:
diamond、diamond_cross、diamond_dot - 星形与特殊形:
star、star_dot、asterisk、cross、x、y、dash、dot、hex、plus、ngon、ray
markers()模块级函数(src/bokeh/plotting/_figure.py)可以直接打印所有可用 marker 类型及快捷键映射,是交互式探索的好帮手:
from bokeh.plotting import markers markers()3.2 线、面积与柱状图
- 线:
line、multi_line、step、segment、bezier、quadratic、arc - 面积:
patch、patches、varea、harea、varea_step、harea_step、ellipse、block - 柱状与矩形:
vbar、hbar、rect、quad、wedge、annular_wedge、annulus - 条带:
vspan、hspan、vstrip、hstrip
以官方入门示例p.line(x, y)为例,它会自动创建对应的Lineglyph 并添加到ColumnDataSource之上;所有 visual 参数(line_color、line_width、fill_color、alpha等)都可以接受标量或数据列名进行向量化映射。
3.3 图像与纹理:image / image_rgba / image_url
image、image_rgba、image_url三个方法用于绘制栅格图像数据,配合mathml、tex、text方法可以叠加数学公式与文本标注,非常适合科学可视化场景。
3.4 堆叠绘图:vbar_stack / hbar_stack / vline_stack / hline_stack / varea_stack / harea_stack
figure提供了一套专门的多层堆叠 API,全部在 src/bokeh/plotting/_figure.py 中实现:
- 柱状堆叠:
vbar_stack(stackers, ...)、hbar_stack(stackers, ...) - 线堆叠:
vline_stack(stackers, ...)、hline_stack(stackers, ...) - 面积堆叠:
varea_stack(stackers, ...)、harea_stack(stackers, ...)
这些方法的参数约定完全一致:stackers是一个数据列名序列,按顺序逐层累加;每个 renderer 的name会被自动设置为对应的列名(配合悬停特殊变量$name使用)。例如vbar_stack(['2016', '2017'], x=10, width=0.9, color=['blue', 'red'], source=source)等价于两次独立的vbar调用(bottom=stack()与bottom=stack('2016')),底层由 _stack.py 中的single_stack/double_stack生成器逐层展开。
3.5 hexbin:一键六边形分箱
hexbin(x, y, size, ...)(src/bokeh/plotting/_figure.py)对二维散点执行等权重六边形分箱,返回(renderer, DataFrame)二元组,其中 DataFrame 包含q、r(轴向坐标)与count(箱内点数)三列。关键参数:
size:六边形尺寸,定义为六边形中心到角点的距离(非 1:1 宽高比时语义随orientation变化);orientation:"pointytop"(默认)或"flattop";palette:默认'Viridis256',按 count 对箱子做颜色映射,指定fill_color后该参数失效;line_color:箱体描边色,默认None;aspect_scale:配合 plot 的aspect_scale绘制正六边形。
官方示例(源码内嵌在 docstring 中)展示了与HoverTool的组合:
import numpy as np from bokeh.models import HoverTool from bokeh.plotting import figure, show x = 2 + 2*np.random.standard_normal(500) y = 2 + 2*np.random.standard_normal(500) p = figure(match_aspect=True, tools="wheel_zoom,reset") p.background_fill_color = '#440154' p.grid.visible = False p.hexbin(x, y, size=0.5, hover_color="pink", hover_alpha=0.8) hover = HoverTool(tooltips=[("count", "@c"), ("(q,r)", "(@q, @r)")]) p.add_tools(hover) show(p)3.6 网络图:graph 与 from_networkx
graph(node_source, edge_source, layout_provider, **kwargs)(src/bokeh/plotting/_figure.py)直接创建GraphRenderer,需要节点数据源、边数据源与一个LayoutProvider。节点和边数据源都会尽力转换为ColumnDataSource。更高层的from_networkx函数(src/bokeh/plotting/graph.py)则可以直接接收 NetworkX 图对象并自动构建布局,用于社交网络、知识图谱等场景。
3.7 等值线:contour
contour(x, y, z, levels, **visuals)(src/bokeh/plotting/_figure.py)基于二维网格数组z计算等值线,返回ContourRenderer:
- 设置
fill_color时生成填充多边形,设置line_color时生成等值线; levels必须单调递增:等值线组数为len(levels),填充多边形组数为len(levels)-1;x、y可省略(默认为np.arange(nx)/np.arange(ny)),z支持掩码数组,np.inf/np.nan会被自动遮蔽;- 向量化的视觉属性需按组数对齐;
fill_color与line_color接受更长的序列并通过bokeh.palettes.linear_palette插值,也接受调色板字典(如bokeh.palettes.Cividis)。
3.8 地理要素:borders / coastlines / land / lakes / ocean / rivers 等
为了简化地图绘制,figure还提供了一组地理要素辅助方法:borders、coastlines、land、lakes、ocean、rivers、projection_boundary、provinces、states。这些方法(实现于 src/bokeh/plotting/_geo_feature.py)需要可选依赖 Cartopy,并以 Cartopy 投影对象为第一参数:
import cartopy.crs as ccrs from bokeh.plotting import figure, show p = figure() p.coastlines(ccrs.PlateCarree()) p.borders(ccrs.PlateCarree(), scale="50m") show(p)scale参数控制要素分辨率,合法值为"110m"、"50m"、"10m";- 线型要素(
coastlines、borders、rivers、provinces)接受multi_line的全部参数; - 面型要素(
land、lakes、ocean、states)接受multi_polygons的全部参数,并额外支持draw_polygon_border(是否绘制几何边界)与draw_polygon_color(边界颜色)两个关键字参数。
四、从源码看 figure 的初始化流程
figure.__init__(src/bokeh/plotting/_figure.py)的执行顺序清晰地揭示了它的设计层次:
def __init__(self, *arg, **kw) -> None: opts = cast(Any, FigureOptions(kw)) # 1. 解析专属选项 names = self.properties() for name in kw.keys(): # 2. 校验未知参数并给出纠错提示 if name not in names: self._raise_attribute_error_with_matches(name, ...) super().__init__(*arg, **kw) # 3. 初始化 Plot 基类 self.x_range = get_range(opts.x_range) # 4. 创建 Range self.y_range = get_range(opts.y_range) self.x_scale = get_scale(self.x_range, opts.x_axis_type) # 5. 选择 Scale self.y_scale = get_scale(self.y_range, opts.y_axis_type) process_axis_and_grid(...) # 6. 装配坐标轴与网格 tool_objs, tool_map = process_tools_arg(self, opts.tools, opts.tooltips) # 7. 创建工具 self.add_tools(*tool_objs) process_active_tools(...) # 8. 设置初始激活工具值得注意的细节:
- 未知关键字会通过
_raise_attribute_error_with_matches给出带纠错建议的错误信息; - 所有专属选项通过
FigureOptions(一个基于Options的轻量解析容器)统一管理,与Plot模型属性互不干扰; - 坐标轴的自动推断(
"auto")完全基于 Range 类型,因此x_range=fruits(字符串列表)会自动得到分类轴,这正是分类柱状图无需显式指定轴类型的原因。
五、如何查阅 figure 的完整 API
figure.rst本身是一个 Sphinx 自动文档指令(autoclass),它会在构建文档时自动展开figure的全部公开成员、未文档化成员与继承成员(排除js_event_callbacks、js_property_callbacks、subscribed_events、model_class_reverse_map等内部回调属性)。查阅完整 API 的途径包括:
- 阅读本文对应章节提到的源码文件:src/bokeh/plotting/_figure.py(类定义与堆叠/地理方法)、src/bokeh/plotting/_plot.py(Range/Scale/轴网格处理)、src/bokeh/plotting/_tools.py(工具解析)、src/bokeh/plotting/glyph_api.py(全部 glyph 方法);
- 参考类型标注文件 src/bokeh/plotting/_figure.pyi 快速浏览方法签名;
- 运行 Bokeh 后通过 Python 的
help(p)或dir(p)交互式查看; - 直接运行仓库中的官方示例(如 examples/basic/bars/basic.py)验证各类方法的效果。
六、实践建议与常见误区
tools与tooltips联动:在figure(tooltips=...)中传入悬停格式,无需显式创建HoverTool,process_tools_arg会自动追加;但若tools中已有HoverTool,则会覆盖其tooltips。active_*参数必须对应已存在的工具名:若传入的字符串不在tools列表中,process_active_tools会抛出ValueError提示。- 小刻度数必须大于 1:显式设置
x_minor_ticks=1会报错,合法取值从 2 开始。 - 分类轴与日期轴无需手动指定:
x_range传入字符串序列自动生成分类轴;"auto"模式对日期值自动选择DatetimeAxis。 - 堆叠方法返回 renderer 列表:
vbar_stack等返回list[GlyphRenderer],每个 renderer 的name即对应的数据列名,便于 hover 中通过$name区分图例项。
掌握figure的构造参数、初始化流程与六大绘图方法族(基础 glyph、堆叠、hexbin、网络图、等值线、地理要素),你就已经掌握了 Bokeh 交互式可视化 90% 的核心能力;在此基础上,配合ColumnDataSource的数据驱动更新与HoverTool的悬停交互,即可构建出完整的浏览器端数据可视化应用。
【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考