求助:Bokeh颜色栏刻度的日期时间格式化方法
解决Bokeh散点图颜色栏日期格式化问题
没问题,我来帮你搞定这个Bokeh颜色栏的日期格式化需求!你说得没错,核心就是要让LinearColorMapper正确映射日期范围,再配合DatetimeTickFormatter把毫秒时间戳转成年/月格式的刻度,和x轴的datetime显示效果对齐。
完整示例代码
下面是一个可直接运行的示例,包含数据生成、颜色映射配置和颜色栏格式化:
from bokeh.plotting import figure, show from bokeh.models import LinearColorMapper, ColorBar, DatetimeTickFormatter from bokeh.palettes import Viridis256 import pandas as pd import numpy as np # 生成模拟数据:带datetime索引的DataFrame dates = pd.date_range(start='2020-01-01', end='2023-12-31', periods=100) df = pd.DataFrame({ 'x': np.random.randn(100), 'y': np.random.randn(100), }, index=dates) # 将datetime索引转换为毫秒级时间戳(Bokeh内部的datetime数值格式) df['color_timestamp'] = df.index.astype('int64') // 10**6 # 配置颜色映射器:指定low和high为数据的最小/最大时间戳 color_mapper = LinearColorMapper( palette=Viridis256, low=df['color_timestamp'].min(), high=df['color_timestamp'].max() ) # 创建绘图对象,x轴设为datetime类型 p = figure(x_axis_type='datetime', width=800, height=500, title='散点图(按日期着色)') # 绘制散点,使用时间戳作为颜色映射的数据源 scatter = p.scatter( x=df.index, y=df['y'], color={'field': 'color_timestamp', 'transform': color_mapper}, size=10, source=df ) # 添加颜色栏,并配置日期格式化器 color_bar = ColorBar( color_mapper=color_mapper, label_standoff=12, formatter=DatetimeTickFormatter( months=['%Y/%m'], # 指定年/月格式 years=['%Y/%m'] ), location=(0, 0) ) p.add_layout(color_bar, 'right') # 显示图表 show(p)
关键步骤解释
转换日期为时间戳
Bokeh的LinearColorMapper只能处理数值类型,所以我们把datetime索引转成毫秒级时间戳(和Bokeh内部处理datetime的格式一致),这样颜色映射才能正确关联日期顺序。设置
LinearColorMapper的low和high
直接用数据中最小和最大的时间戳作为映射范围,确保颜色栏的刻度范围和数据的日期范围完全匹配,避免出现多余或缺失的刻度。配置
DatetimeTickFormatter
给ColorBar指定这个格式化器,它会把毫秒时间戳自动解析为datetime对象,并按照你指定的%Y/%m格式显示(年份/月份)。你还可以根据需要调整格式字符串,比如'%Y-%m'或者只显示年份'%Y'。
额外优化:自定义刻度数量
如果想要更少的刻度,可以配合FixedTicker手动指定需要显示的日期时间戳,比如:
from bokeh.models import FixedTicker # 手动指定几个关键日期的时间戳(毫秒) ticker_dates = pd.date_range(start='2020-01-01', end='2023-12-31', freq='Y') ticker_values = ticker_dates.astype('int64') // 10**6 color_bar = ColorBar( color_mapper=color_mapper, label_standoff=12, formatter=DatetimeTickFormatter(months=['%Y/%m']), ticker=FixedTicker(ticks=ticker_values), # 使用自定义刻度 location=(0, 0) )
这样就能让颜色栏只显示每年年初的刻度,更简洁。
内容的提问来源于stack exchange,提问作者Stefan Meili
相关产品推荐
相关产品推荐

