如何为Bokeh坐标轴刻度配置调用prefixed.Float的格式化器?
解决Bokeh坐标轴使用prefixed.Float格式化的问题
方法一:手动生成刻度与标签(Python端处理)
如果数据范围已知、刻度不需要动态调整,直接在Python端用prefixed.Float生成格式化后的标签,再通过固定刻度器指定坐标轴的刻度值和对应标签:
- 导入所需库
from bokeh.plotting import figure, show from bokeh.models import FixedTicker, FixedTickFormatter import prefixed
- 定义刻度值并生成格式化标签
根据实际数据范围设置需要显示的刻度值,再用prefixed.Float格式化为目标样式:
# 根据你的数据范围调整刻度值 tick_values = [0, 100, 1000, 100000, 1000000] # 生成带SI前缀的标签,保留两位小数 tick_labels = [f'{prefixed.Float(val):.2h}' for val in tick_values]
- 配置坐标轴
将坐标轴的刻度器设为FixedTicker,格式化器设为FixedTickFormatter,绑定刻度值和标签:
p = figure(x_range=(0, 1.1 * 1000000)) p.xaxis.ticker = FixedTicker(ticks=tick_values) p.xaxis.formatter = FixedTickFormatter(ticks=tick_labels) # 示例曲线 p.line([0, 1000000], [0, 20]) show(p)
这种方法完全复用Python的prefixed库,无需编写JS,适合刻度固定的场景。
方法二:用JS实现类似prefixed.Float的逻辑(动态刻度)
如果需要坐标轴刻度随视图缩放动态调整,把prefixed.Float的核心逻辑转成JS,通过FuncTickFormatter调用:
from bokeh.plotting import figure, show from bokeh.models import FuncTickFormatter p = figure(x_range=(0, 1.1 * 1000000)) # 编写JS函数实现SI前缀格式化,对应prefixed.Float的.2h格式 p.xaxis.formatter = FuncTickFormatter(code=""" function formatTick(value) { const posPrefixes = ['', 'k', 'M', 'G', 'T']; const negPrefixes = ['', 'm', 'µ', 'n', 'p']; if (value === 0) return '0.00'; const absVal = Math.abs(value); let exponent = Math.floor(Math.log10(absVal) / 3); let prefix = ''; let scaledVal = value; if (exponent >= 0) { exponent = Math.min(exponent, posPrefixes.length - 1); prefix = posPrefixes[exponent]; scaledVal = value / (10 ** (exponent * 3)); } else { exponent = Math.abs(exponent); exponent = Math.min(exponent, negPrefixes.length - 1); prefix = negPrefixes[exponent]; scaledVal = value * (10 ** (exponent * 3)); } return scaledVal.toFixed(2) + prefix; } return formatTick(tick); """) p.line([0, 1000000], [0, 20]) show(p)
这个JS函数实现了和prefixed.Float(val):.2h近似的效果——自动匹配SI前缀并保留两位小数,支持动态调整的刻度。如果需要更复杂的格式,可以根据prefixed的源码逻辑进一步完善JS代码。
内容的提问来源于stack exchange,提问作者Trick
相关产品推荐
相关产品推荐

