news 2026/9/14 17:03:40

Bokeh 数学符号渲染完全指南:在图表与控件中使用 LaTeX 和 MathML

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Bokeh 数学符号渲染完全指南:在图表与控件中使用 LaTeX 和 MathML

Bokeh 数学符号渲染完全指南:在图表与控件中使用 LaTeX 和 MathML

【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh

Bokeh 原生支持在图表中渲染数学公式,允许开发者使用 LaTeX 与 MathML 两种标记语言来书写轴标签、标题、刻度标签、标注(Label)以及各类控件文本。本指南以 Bokeh 用户手册的数学符号(Mathematical notation)章节为核心,结合仓库中 examples/styling/mathtext 目录下的完整示例与bokeh.models.text源码实现,系统讲解如何在当前项目中为图表注入专业、美观的数学排版,读完后你将能熟练使用$$...$$\[...\]\(...\)定界符书写 LaTeX,并掌握MathML模型与major_label_overrides等核心配置方法。

一、Bokeh 数学符号支持总览

Bokeh 支持用 LaTeX 和 MathML 两种标记语言表达数学记号,目前可应用于以下元素:

元素说明相关文档
轴标签(Axis labels)通过axis_label属性设置样式指南-绘图章节
刻度标签(Tick labels)通过major_label_overrides覆盖见下文"刻度标签"小节
标题(Titles)通过title属性设置基础注解-标题
标注(Labels)Label注解对象基础注解-标注
颜色条(Color bars)颜色条上的标签文本基础注解-颜色条
RangeSlider / Slider 控件控件的title参数交互-控件
Div / Paragraph 控件控件正文中的任意位置交互-控件

渲染层面,Bokeh 依赖 MathJax 库来处理 LaTeX 与 MathML 的排版。这意味着你无需在页面中自行引入其他数学渲染库,Bokeh 已经集成了完整的 MathJax 支持。

从源码结构看,Bokeh 在 src/bokeh/models/text.py 中定义了完整的文本模型体系:抽象基类BaseText提供text属性(必填字符串),抽象类MathText作为数学内容的基类,其下派生出TeX(LaTeX 记号)、MathML(MathML 记号)、Ascii(AsciiMath 记号)三个具体模型,另有PlainText表示普通文本。这套模型体系正是 Bokeh 将数学文本作为"一等公民"传递到前端的核心载体。

注意(重要):如果你使用components函数将 Bokeh 组件嵌入自定义 HTML 模板,务必在模板中显式引入bokeh-mathjax-资源,否则数学公式将无法渲染。

二、使用 LaTeX 记号

2.1 定界符:如何让 Bokeh 识别数学表达式

要使用 LaTeX 记号,只需把字符串直接传给任意受支持的元素。该字符串必须以 MathJax 默认定界符开头和结尾:

  • $$...$$:块级数学(display math)
  • \[...\]:块级数学的另一种写法
  • \(...\):行内数学(inline math)

例如:r"$$\sin(x)$$"。注意示例代码中普遍使用 Python 原始字符串(r"..."),以避免反斜杠被 Python 转义。

仓库示例 latex_axis_labels_titles_labels.py 同时演示了三种定界符的用法:

from numpy import arange, pi, sin from bokeh.models.annotations.labels import Label from bokeh.plotting import figure, show x = arange(-2*pi, 2*pi, 0.1) y = sin(x) p = figure(height=250, title=r"$$\sin(x)$$ for \[x\] between \(-2\pi\) and $$2\pi$$") p.scatter(x, y, alpha=0.6, size=7) label = Label( text=r"$$y = \sin(x)$$", x=150, y=130, x_units="screen", y_units="screen", ) p.add_layout(label) p.yaxis.axis_label = r"\(\sin(x)\)" p.xaxis.axis_label = r"\[x\pi\]" show(p)

2.2 LaTeX 应用于轴标签、标题与标注

将 LaTeX 用作轴标签、标题或标注时,做法完全一致:传入以 MathJax 默认定界符开头和结尾的原始字符串字面量即可。上面的示例中,titleLabel.textp.yaxis.axis_labelp.xaxis.axis_label均直接接收了带定界符的 LaTeX 字符串。

2.3 LaTeX 应用于刻度标签(major_label_overrides)

要给刻度标签添加 LaTeX 记号,需要使用轴对象的major_label_overrides方法。从源码 src/bokeh/models/axes.py 可以看到其定义:

major_label_overrides = Dict(Either(Float, String), TextLike, default={}, help=""" Provide explicit tick label values for specific tick locations that override normal formatting. """)

该属性接受一个字典:键是刻度位置的原始数值(或字符串),值是你自定义的替换文本(TextLike类型,意味着它可以是普通字符串,也可以是MathMLTeX等文本模型)。Bokeh 会用字典中的值覆盖对应位置的默认格式化标签。

仓库示例 latex_tick_labels.py 演示了电阻-电流关系图中用 LaTeX 替换普通刻度文本的方法:

from numpy import arange from bokeh.plotting import figure, show x = arange(1, 4.5, 0.25) y = 1 / x plot = figure(height=200) plot.title = "Current over Resistance at a static voltage of 1 volt" plot.scatter(x, y, fill_color="blue", size=5) plot.line(x, y, color="darkgrey") plot.xaxis.axis_label = "Resistance" plot.xaxis.ticker = [1, 2, 3, 4] plot.xaxis.major_label_overrides = { 1: r"1 $$\Omega$$", 2: r"2 $$\Omega$$", 3: r"3 $$\Omega$$", 4: r"4 $$\Omega$$", } plot.yaxis.axis_label = "Current" plot.yaxis.ticker = [0.2, 0.4, 0.6, 0.8, 1.0] plot.yaxis.major_label_overrides = { 0.2: "0.2 $$A$$", 0.4: "0.4 $$A$$", 0.6: "0.6 $$A$$", 0.8: "0.8 $$A$$", 1: "1 $$A$$", } show(plot)

关键点:先用plot.xaxis.ticker = [1, 2, 3, 4]明确指定刻度位置,再用major_label_overrides把每个位置映射到带单位符号(欧姆 Ω、安培 A)的 LaTeX 文本,从而实现"单位符号以数学字体排版"的效果。

2.4 LaTeX 应用于 RangeSlider 与 Slider 控件标题

在 RangeSlider 或 Slider 控件的title参数中传入带定界符的原始字符串,即可让控件标题显示数学公式。仓库示例 latex_slider_widget_title.py 演示:

from bokeh.io import show from bokeh.models import Slider slider = Slider(start=0, end=10, value=1, step=.1, title=r"$$\delta \text{ (damping factor, 1/s)}$$") show(slider)

这里除了数学符号\delta外,还借助\text{}扩展把普通文字 "damping factor, 1/s" 嵌入数学表达式中,这正是 LaTeX 扩展的典型用法(见下文第五节)。

2.5 LaTeX 应用于 Div 与 Paragraph 控件

在 Div 或 Paragraph 控件的文本中,可以在字符串的任意位置使用 MathJax 默认定界符,实现"正文中混排数学公式"的效果。仓库示例 latex_div_widget.py 演示:

from bokeh.io import show from bokeh.models import Div div = Div( width=400, height=100, background="#fafafa", text=r"The Pythagorean identity is $$\sin^2(x) + \cos^2(x) = 1$$", ) show(div)

关闭数学渲染:如果不希望 Div 或 Paragraph 对数学记号做渲染,可以把控件的disable_math属性设为True。该属性在 src/bokeh/models/widgets/markups.py 中定义为disable_math = Bool(False, ...),默认开启数学处理;Markdown 控件同样支持该开关(见 src/bokeh/models/widgets/markdown.py)。

三、调整渲染后数学文本的样式

Bokeh 标准的文本属性(text properties)同样作用于渲染后的数学文本:

  • text_font_size改变字号;
  • text_color改变颜色。

例如,原文档给出的轴标签样式设置:

p.xaxis.axis_label = r"$$\nu \:(10^{15} s^{-1})$$" p.xaxis.axis_label_text_color = "green" p.xaxis.axis_label_text_font_size = "50px"

在 latex_blackbody_radiation.py 中可以看到更完整的组合用法:白色轴标签配合暗色主题dark_minimal,并使用了\text{}在公式中混排单位文本:

p.xaxis.axis_label = r"$$\nu \:(10^{15}\ \text{Hz})$$" p.yaxis.axis_label = r"$$B_\nu(\nu, T) \quad\left(10^{-9}\ \text{W} / (\text{m}^2 \cdot \text{sr} \cdot \text{Hz})\right)$$"

在 latex_bessel.py 中,标题、轴标签与Label标注共同使用了复杂的求和公式与上下标:

p = figure( width=700, height=500, title=( r"Bessel functions of the first kind: $$J_\alpha(x) = \sum_{m=0}^{\infty}" r"\frac{(-1)^m}{m!\:\Gamma(m+\alpha+1)} \left(\frac{x}{2}\right)^{2m+\alpha}$$" ), ) ... p.title.text_font_size = "14px" p.title.text_color = "white" ... p.add_layout(Label(text=f"$$J_{i}(x)$$", x=xlabel, y=ylabel, text_color="white"))

此外,在 Bokeh 主题(theme)中定义的文本颜色与字号对数学文本同样生效。例如上述两个示例分别通过curdoc().theme = 'night_sky'curdoc().theme = 'dark_minimal'切换主题,数学公式会随之继承主题中的文本样式。

四、LaTeX 扩展与渲染限制

除了基础数学排版,你还可以使用 MathJax 内置的 LaTeX 扩展:

  • \text{}:在数学表达式中插入字面文本,例如\text{Hz}\text{ (damping factor, 1/s)},非常适合"物理量 + 单位"的场景;
  • color 扩展:直接改变渲染颜色,例如\color{white} \sin(x)

需要特别注意的是:用 LaTeX 扩展(如\color{})设置的文本属性,优先级高于代码中或主题里设置的其他文本属性,也就是说扩展声明会覆盖同位置的text_color等设置。

同时要明确一个限制:MathJax 对 LaTeX 的支持存在边界,它并不完全等同于完整的 TeX/LaTeX 实现——例如 MathJax 主要支持数学模式(math-mode)下的宏,不支持文本模式(text-mode)宏。从 src/bokeh/models/text.py 中TeX模型的文档注释也能看到这一说明。对复杂宏或扩展行为有疑问时,应以 MathJax 官方文档中 "Differences from Actual TeX" 一节为准,按 MathJax 的实际能力编写公式。

五、使用 MathML 记号

除 LaTeX 外,Bokeh 还支持 MathML。与 LaTeX 的"字符串 + 定界符"方式不同,MathML 需要直接使用bokeh.models.text.MathML模型。该模型的text属性接受一个包含 MathML 标记的字符串,例如 mathml_axis_labels.py 中的演示:

from numpy import arange from bokeh.models import MathML from bokeh.plotting import figure, show x = arange(-10, 10, 0.1) y = (x * 0.5) ** 2 mathml = """ <math> <mrow> <mfrac> <mn>1</mn> <mn>4</mn> </mfrac> <msup> <mi>x</mi> <mn>2</mn> </msup> </mrow> </math> """ plot = figure(height=200) plot.line(x, y) plot.xaxis.axis_label = MathML(text=mathml) show(plot)

上面的 MathML 字符串等价于数学表达式1/4 · x²<mfrac>表示分数,<msup>表示上标,<mi>/<mn>分别表示标识符(变量)与数字。

与 LaTeX 类似,MathML 渲染结果同样支持标准文本属性:

plot.xaxis.axis_label = MathML(text=mathml) plot.xaxis.axis_label_text_color = "green" plot.xaxis.axis_label_text_font_size = "50px"

从源码 src/bokeh/models/text.py 可见,MathML继承自MathText(再继承自BaseText),BaseText定义了必填的text属性;同时MathML.__init__支持位置参数直接传入文本,即MathML("<math>...</math>")MathML(text="...")等价。由于MathML本身属于TextLike类型族,凡是接受TextLike的属性(如major_label_overrides的值、轴标签等)都可以直接传入MathML实例。

六、更多实战示例与进一步阅读

仓库 examples/styling/mathtext 目录还提供了多个可直接运行的高级示例,可作为深入学习的素材:

  • latex_normal_distribution.py、latex_schrodinger.py:物理/统计公式在标题、轴标签中的典型应用;
  • latex_outline_shapes.py:数学文本与其他图形的组合排版;
  • latex_blackbody_radiation.py:轴标签与 Div 控件中混排公式 +\text{}单位文本 + 主题联动;
  • latex_bessel.py:求和、分数、希腊字母等复杂公式在标题、轴标签与标注上的综合演示。

这些示例的运行方式与普通 Bokeh 脚本一致:直接执行python examples/styling/mathtext/latex_bessel.py即可在浏览器中查看渲染效果(部分示例依赖scipy,如贝塞尔函数示例)。

七、要点速查

  1. 定界符三件套$$...$$\[...\]\(...\),字符串用r"..."原始字符串书写;
  2. 应用范围:轴标签、标题、标注、刻度标签(major_label_overrides)、颜色条、Slider/RangeSlider 标题、Div/Paragraph 文本;
  3. 刻度标签axis.major_label_overrides = {位置: 文本},文本可为字符串或MathML/TeX模型;
  4. 关闭渲染:Div/Paragraph 设置disable_math=True
  5. MathML:使用MathML(text="...")模型,支持text_font_sizetext_color
  6. 样式继承:文本属性与主题均对数学文本生效,但\color{}等 LaTeX 扩展声明的样式优先级更高;
  7. 嵌入注意:使用components时记得在 HTML 模板中包含bokeh-mathjax-资源。

【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 17:02:31

2026 GEO工具选型指南:从RAG原理到五款主流产品PoC验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 17:01:59

LaTeX数学动画像素跳动的根源与七步精准控制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 16:59:17

具身智能人机交互数据采集平台:从机械臂选型到ROS2架构

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 16:58:04

Pandas DataFrame核心技术与数据分析实战指南

1. Pandas DataFrame&#xff1a;数据分析的基石工具DataFrame作为Pandas库的核心数据结构&#xff0c;已经成为现代数据分析的标准工具。这种二维表格结构完美融合了SQL表的灵活性和Excel电子表格的直观性&#xff0c;同时提供了强大的编程接口。我在处理电商用户行为数据时&a…

作者头像 李华
网站建设 2026/9/14 16:56:21

股票筹码主图指标:算法解析与实战应用

1. 筹码主图指标的设计初衷在股票交易中&#xff0c;筹码分布是判断主力资金动向的重要依据。传统的K线图只能展示价格波动&#xff0c;而筹码主图则能直观反映不同价位上的持仓成本分布。我设计这个指标的初衷&#xff0c;是想解决三个核心问题&#xff1a;识别主力建仓区域&a…

作者头像 李华