Bokeh水平堆叠条形图转换问题:垂直转水平未生效
解决Bokeh垂直堆叠条形图转水平的问题
首先,你的问题出在调用hbar方法的方式不对——你是在已经创建好的垂直Bar图表上添加了额外的水平条形元素,而不是直接生成水平堆叠的条形图。下面分两种方式给你解决方案:
一、基于你当前使用的bokeh.charts.Bar(旧版本)
旧版的Bar类支持通过orientation参数直接指定水平方向,不需要额外调用hbar。修改你的代码如下:
from bokeh.charts import Bar, output_file, show from bokeh.models import HoverTool # 创建数据 data = { 'customer': ['Cust 1', 'Cust 2', 'Cust 1', 'Cust 3', 'Cust 1', 'Cust 2'], 'itemSold': ['python', 'python', 'pypy', 'pypy', 'jython', 'jython'], 'sales': [200, 600, 850, 620, 400, 550] } # 创建hover tooltip hover = HoverTool(tooltips=[ ("sales", "@sales"), ("customer", "@customer"), ("itemSold", "@itemSold") ]) # 设置orientation='horizontal'生成水平堆叠条形图 bar = Bar( data, values='sales', label='itemSold', # 现在这个会对应y轴 stack='customer', title="Python itemSold Sampling", legend='top_right', sizing_mode="scale_both", tools=[hover, 'wheel_zoom'], orientation='horizontal' # 关键参数:指定水平方向 ) output_file("stacked.html") show(bar)
这样就能直接生成水平堆叠的条形图,不需要再调用hbar方法。
二、推荐使用Bokeh新版本的bokeh.plotting(更稳定,官方推荐)
注意:bokeh.charts已经在Bokeh 0.12.10版本后被废弃,官方现在推荐使用bokeh.plotting模块来创建图表。下面是用新版本API实现水平堆叠条形图的示例:
from bokeh.plotting import figure, output_file, show from bokeh.models import HoverTool, ColumnDataSource from bokeh.palettes import Category10 # 先整理数据为适合堆叠的格式 # 按itemSold分组,每个customer对应sales值 data = { 'itemSold': ['python', 'pypy', 'jython'], 'Cust 1': [200, 850, 400], 'Cust 2': [600, 0, 550], # pypy没有Cust2的销售,填0 'Cust 3': [0, 620, 0] # python和jython没有Cust3的销售,填0 } source = ColumnDataSource(data) # 定义堆叠的客户列表 customers = ['Cust 1', 'Cust 2', 'Cust 3'] colors = Category10[len(customers)] # 创建figure,设置y轴为itemSold,x轴为sales p = figure( y_range=data['itemSold'], title="Python itemSold Sampling", sizing_mode="scale_both", tools=['wheel_zoom'] ) # 使用hbar_stack创建水平堆叠条形图 renderers = p.hbar_stack( customers, y='itemSold', right=data, source=source, height=0.5, color=colors, legend_label=customers ) # 添加hover工具 hover = HoverTool(tooltips=[ ("customer", "$name"), ("sales", "@$name"), ("itemSold", "@itemSold") ], renderers=renderers) p.add_tools(hover) # 调整图例位置 p.legend.location = "top_right" output_file("stacked_new.html") show(p)
这个版本的API更灵活,也更符合当前Bokeh的发展方向,建议你迁移到这个方式。
为什么你的原代码没用?
你原代码中调用bar.hbar(...),其实是在原来的垂直Bar图表上额外绘制了一组独立的水平条形,而不是把原来的垂直堆叠图转换成水平的。所以你看到的还是原来的垂直图,只是叠加了新的元素,这不是你想要的效果。
内容的提问来源于stack exchange,提问作者Young Pattewa
相关产品推荐
相关产品推荐

