[英]Bokeh Position Legend outside plot area for stacked vbar
I have a stacked vbar chart in Bokeh, a simplified version of which can be reproduced with: 我在Bokeh中有一个堆叠的vbar图表,其简化版可以复制为:
from bokeh.plotting import figure
from bokeh.io import show
months = ['JAN', 'FEB', 'MAR']
categories = ["cat1", "cat2", "cat3"]
data = {"month" : months,
"cat1" : [1, 4, 12],
"cat2" : [2, 5, 3],
"cat3" : [5, 6, 1]}
colors = ["#c9d9d3", "#718dbf", "#e84d60"]
p = figure(x_range=months, plot_height=250, title="Categories by month",
toolbar_location=None)
p.vbar_stack(categories, x='month', width=0.9, color=colors, source=data)
show(p)
I want to add a legend to the chart, but my real chart has a lot of categories in the stacks and therefore the legend would be very large, so I want it to be outside the plot area to the right. 我想在图表中添加图例,但是我的真实图表在堆栈中有很多类别,因此图例会非常大,因此我希望它位于右侧的绘图区域之外。
There's a SO answer here which explains how to add a legend outside of the plot area, but in the example given each glyph rendered is assigned to a variable which is then labelled and added to a Legend
object. 这里有一个SO答案,它解释了如何在绘图区域之外添加图例,但是在示例中,给定的每个字形都分配给一个变量,该变量随后被标记并添加到
Legend
对象。 I understand how to do that, but I believe the vbar_stack
method creates mutliple glyphs in a single call, so I don't know how to label these and add them to a separate Legend
object to place outside the chart area? 我知道该怎么做,但是我相信
vbar_stack
方法可以在一个调用中创建多个字形,所以我不知道如何标记这些字形并将它们添加到单独的Legend
对象中以放置在图表区域之外?
Alternatively, is there a simpler way to use the legend
argument when calling vbar_stack
and then locate the legend outside the chart area? 或者,是否有更简单的方法在调用
vbar_stack
时使用legend
参数,然后在图表区域之外定位图例?
Any help much appreciated. 任何帮助,不胜感激。
For anyone interested, have now fixed this using simple indexing of the vbar_stack
glyphs. 对于任何感兴趣的人,现在都可以使用
vbar_stack
符号的简单索引来解决此问题。 Solution below: 解决方案如下:
from bokeh.plotting import figure
from bokeh.io import show
from bokeh.models import Legend
months = ['JAN', 'FEB', 'MAR']
categories = ["cat1", "cat2", "cat3"]
data = {"month" : months,
"cat1" : [1, 4, 12],
"cat2" : [2, 5, 3],
"cat3" : [5, 6, 1]}
colors = ["#c9d9d3", "#718dbf", "#e84d60"]
p = figure(x_range=months, plot_height=250, title="Categories by month",
toolbar_location=None)
v = p.vbar_stack(categories, x='month', width=0.9, color=colors, source=data)
legend = Legend(items=[
("cat1", [v[0]]),
("cat2", [v[1]]),
("cat3", [v[2]]),
], location=(0, -30))
p.add_layout(legend, 'right')
show(p)
Thanks Toby Petty for your answer. 感谢Toby Petty的回答。
I have slightly improved your code so that it automatically graps the categories from the source data and assigns colors. 我对您的代码做了一些改进,以便它可以自动从源数据中提取类别并分配颜色。 I thought this might be handy as the categories are often not explicitly stored in a variable and have to be taken from the data.
我认为这可能很方便,因为类别通常没有显式存储在变量中,而必须从数据中获取。
from bokeh.plotting import figure
from bokeh.io import show
from bokeh.models import Legend
from bokeh.palettes import brewer
months = ['JAN', 'FEB', 'MAR']
data = {"month" : months,
"cat1" : [1, 4, 12],
"cat2" : [2, 5, 3],
"cat3" : [5, 6, 1],
"cat4" : [8, 2, 1],
"cat5" : [1, 1, 3]}
categories = list(data.keys())
categories.remove('month')
colors = brewer['YlGnBu'][len(categories)]
p = figure(x_range=months, plot_height=250, title="Categories by month",
toolbar_location=None)
v = p.vbar_stack(categories, x='month', width=0.9, color=colors, source=data)
legend = Legend(items=[(x, [v[i]]) for i, x in enumerate(categories)], location=(0, -30))
p.add_layout(legend, 'right')
show(p)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.