我有一个使用极角投影的Bokeh散点图(bokeh==1.0.4
)。这些点的半径对应于ColumnDataSource中的RadiusSize
,而颜色对应于DepthClass
。
我创建了第二个“虚拟”散点图,以获得与fill_color
(depth_legend
)相对应的图例。我想要第二个与半径相对应的图例。 RadiusSize
数据是1到5的整数。我正在寻找与this matplotlib legend非常相似的第二个图例(请参见接受的答案)。
这是我相关的绘图代码:
def make_scatter(event_data):
'''
Create a polar scatter figure
Parameters
----------
event_data: Pandas dataframe
Returns
-------
p: Bokeh Figure object
'''
cds = create_cds(event_data)
p = figure(
title="",
name="scatter_fig",
width=600, height=600,
tools='',
)
# Project data into polar coordinates
# customjs from bryevdv (https://github.com/bokeh/bokeh/issues/657)
polarx = CustomJSTransform(args=dict(source=cds), v_func='''
const new_xs = new Array(source.data.elev_project_vectors.length)
for(var i = 0; i < new_xs.length; i++) {
new_xs[i] = source.data.elev_project_vectors[i] * Math.sin(source.data.elev_angles[i] )
}
return new_xs
''')
polary = CustomJSTransform(args=dict(source=cds), v_func='''
const new_ys = new Array(source.data.elev_project_vectors.length)
for(var i = 0; i < new_ys.length; i++) {
new_ys[i] = source.data.elev_project_vectors[i] * Math.cos(source.data.elev_angles[i] )
}
return new_ys
''')
event_scatter = p.scatter(
x=transform('elev_project_vectors', polarx),
y=transform('elev_project_vectors', polary),
radius='RadiusSize',
fill_color='DepthClass', fill_alpha=1.0,
name='event_scatter',
source=cds)
# This is a dummy glyph just to have consistent colors for a custom legend
event_scatter_dummy = p.scatter(
x=[1,2,3],
y=[1,2,3],
radius=0,
fill_color=['green','yellow','red'], fill_alpha=1.0,
name='event_scatter_dummy',
)
depth_legend = Legend(items=[
LegendItem(label='crown < 12"', renderers=[event_scatter_dummy], index=0),
LegendItem(label='crown 12-44"', renderers=[event_scatter_dummy], index=1),
LegendItem(label='crown > 44"', renderers=[event_scatter_dummy], index=2),
])
p.add_layout(depth_legend)
return p
这是当前Bokeh图形的屏幕截图,其中单个图例对应于fill_color
:
理想情况下,第二个图例将具有标签(R1,R2,R3,R4,R5)和相应范围的递增半径的圆。我如何获得第二个传说?
答案 0 :(得分:0)
我能够通过创建一个虚拟的看不见的圆,然后创建并堆叠五个单独的Legend
实例来渲染这个虚拟的圆,来破解这些问题。每个图例都需要使用location
和label_standoff
进行自定义定位,以正确对齐。然后,我遍历圆形字形并调整其大小,使其与绘制数据的半径相对应。
这不是理想的解决方案,因为图例与实际数据无关,但是它可以直观地完成工作。
这是散景代码:
event_radius_dummy_1 = p.circle(
1,1,
radius=0,
fill_alpha=0.0, line_color='black',
name='event_radius_dummy_1'
)
event_legend1 = Legend(items=[
LegendItem(label='R1', renderers=[event_radius_dummy_1])],
location=(20,554), label_standoff=10, label_height=3)
event_legend2 = Legend(items=[
LegendItem(label='R2', renderers=[event_radius_dummy_1])],
location=(14,532), label_standoff=5)
event_legend3 = Legend(items=[
LegendItem(label='R3', renderers=[event_radius_dummy_1])],
location=(8,507), label_standoff=0)
event_legend4 = Legend(items=[
LegendItem(label='R4', renderers=[event_radius_dummy_1])],
location=(2,479), label_standoff=-5)
event_legend5 = Legend(items=[
LegendItem(label='R5', renderers=[event_radius_dummy_1])],
location=(-4,447), label_standoff=-10)
event_legend_list = [event_legend1,event_legend2,event_legend3,event_legend4,event_legend5]
for legend in event_legend_list:
p.add_layout(legend)
size_list = [15,26,37,48,59]
index_list = [1,2,3,4,5]
for index, size in zip(index_list, size_list):
p.legend[index].glyph_height = size
p.legend[index].glyph_width = size
p.legend[index].padding = 0
p.legend[index].margin = 0
p.legend[index].border_line_alpha = 0
p.legend[index].background_fill_alpha = 0