散景第二个图例显示散点半径

时间:2019-05-28 14:00:44

标签: python bokeh

我有一个使用极角投影的Bokeh散点图(bokeh==1.0.4)。这些点的半径对应于ColumnDataSource中的RadiusSize,而颜色对应于DepthClass

我创建了第二个“虚拟”散点图,以获得与fill_colordepth_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_colorenter image description here 理想情况下,第二个图例将具有标签(R1,R2,R3,R4,R5)和相应范围的递增半径的圆。我如何获得第二个传说?

1 个答案:

答案 0 :(得分:0)

我能够通过创建一个虚拟的看不见的圆,然后创建并堆叠五个单独的Legend实例来渲染这个虚拟的圆,来破解这些问题。每个图例都需要使用locationlabel_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

结果图: enter image description here