You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bokeh垂直条形图格式问题:宽度无法调整及月份标签异常

嘿,我来帮你搞定这个Bokeh条形图的问题!咱们先拆解下你遇到的三个问题的核心原因,再给你两个可行的解决方案:

问题原因拆解

  1. datetime轴下width参数无效:Bokeh的datetime类型轴,width参数是按毫秒计算的!你设置的0.5或100毫秒连1秒都不到,自然看不到条形宽度变化。一个月大概有2.6×10⁹毫秒,得设置这个量级的数值才会有效果。
  2. 改用MONTH数值后标签消失:你用的MonthsTicker是专门给datetime轴设计的刻度器,当x轴变成1-12的整数数值时,这个ticker完全不匹配,所以标签直接消失了。
  3. 移除ticker后显示毫秒值:因为你一开始设置了x_axis_type='datetime',即使x换成了MONTH数值,Bokeh还是会把这些整数当成「从1970-01-01开始的毫秒数」来解析,所以才会显示奇怪的日期数值。

解决方案

方案1:保留datetime轴,正确设置宽度和标签

如果你想保留时间轴的连续性,可以继续用DATE列做x轴,只需要调整width的单位,再优化标签显示:

from bokeh.plotting import figure, show
from bokeh.models import MonthsTicker, DatetimeTickFormatter

# 初始化图表
p1 = figure(
    title='Monthly Food Spendings',
    x_axis_label='Month',
    plot_height=300,
    plot_width=600,
    x_axis_type='datetime'
)

# 设置x轴刻度为1-12月,标签显示月份名称(或数字)
p1.xaxis.ticker = MonthsTicker(months=[1,2,3,4,5,6,7,8,9,10,11,12])
# 可选:显示月份缩写(Jan/Feb)或全名(January/February)
p1.xaxis.formatter = DatetimeTickFormatter(months=["%b", "%B"])
# 如果你想显示月份数字,换成NumeralTickFormatter:
# from bokeh.models import NumeralTickFormatter
# p1.xaxis.formatter = NumeralTickFormatter(format="%m")

# 设置条形宽度为25天对应的毫秒数(25*24*60*60*1000=2160000000)
p1.vbar(
    x=MonthlyFoodSpendingsResult['DATE'],
    top=MonthlyFoodSpendingsResult['SUM'],
    width=2160000000  # 可根据需求调整,比如20天就是1728000000
)

show(p1)

方案2:用分类轴(更省心的月度标签)

如果不想折腾datetime的毫秒计算,直接把月份转成分类标签(比如「2016-01」或「Jan」),用分类轴绘制,宽度设置会更直观:

from bokeh.plotting import figure, show
from bokeh.models import FactorRange

# 给DataFrame添加自定义月份标签列
MonthlyFoodSpendingsResult['MONTH_LABEL'] = MonthlyFoodSpendingsResult['DATE'].dt.strftime('%Y-%m')
# 也可以换成月份缩写:.dt.strftime('%b') → "Jan", "Feb"

# 提取分类标签列表(确保顺序和数据一致)
month_labels = MonthlyFoodSpendingsResult['MONTH_LABEL'].tolist()

# 初始化分类轴图表
p2 = figure(
    title='Monthly Food Spendings',
    x_axis_label='Month',
    plot_height=300,
    plot_width=600,
    x_range=FactorRange(factors=month_labels)
)

# 这里的width是分类间隔的比例,0.8表示每个条形占分类宽度的80%
p2.vbar(
    x='MONTH_LABEL',
    top='SUM',
    width=0.8,
    source=MonthlyFoodSpendingsResult  # 使用source更高效,也支持交互式操作
)

# 让标签垂直显示,避免重叠
p2.xaxis.major_label_orientation = "vertical"

show(p2)

选择建议

  • 如果你需要保留时间轴的连续性(比如后续要添加跨年数据),选方案1;
  • 如果更看重标签的直观性和设置简单,方案2绝对是更省心的选择。

内容的提问来源于stack exchange,提问作者o.sk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:15:18