Bokeh垂直条形图格式问题:宽度无法调整及月份标签异常
嘿,我来帮你搞定这个Bokeh条形图的问题!咱们先拆解下你遇到的三个问题的核心原因,再给你两个可行的解决方案:
问题原因拆解
- datetime轴下width参数无效:Bokeh的datetime类型轴,
width参数是按毫秒计算的!你设置的0.5或100毫秒连1秒都不到,自然看不到条形宽度变化。一个月大概有2.6×10⁹毫秒,得设置这个量级的数值才会有效果。 - 改用MONTH数值后标签消失:你用的
MonthsTicker是专门给datetime轴设计的刻度器,当x轴变成1-12的整数数值时,这个ticker完全不匹配,所以标签直接消失了。 - 移除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
相关产品推荐
相关产品推荐

