【问题标题】:Position the legend outside the plot area with Bokeh使用 Bokeh 将图例定位在绘图区域之外
【发布时间】:2021-01-20 20:31:14
【问题描述】:

我正在按照here找到的示例进行绘图

不幸的是,我需要显示 17 条曲线,并且图例与它们重叠。我知道我可以创建一个可以显示在绘图区域外的图例对象,例如 here,但我有 17 条曲线,因此使用循环更方便。

你知道如何结合这两种方法吗?

【问题讨论】:

    标签: python plot legend bokeh


    【解决方案1】:

    好的,我找到了解决方案。请参阅下面的代码,其中我刚刚修改了交互式图例示例:

    import pandas as pd
    from bokeh.palettes import Spectral4
    from bokeh.plotting import figure, output_file, show
    from bokeh.sampledata.stocks import AAPL, IBM, MSFT, GOOG
    from bokeh.models import Legend
    from bokeh.io import output_notebook
    
    output_notebook()
    
    p = figure(plot_width=800, plot_height=250, x_axis_type="datetime", toolbar_location='above')
    p.title.text = 'Click on legend entries to mute the corresponding lines'
    
    legend_it = []
    
    for data, name, color in zip([AAPL, IBM, MSFT, GOOG], ["AAPL", "IBM", "MSFT", "GOOG"], Spectral4):
        df = pd.DataFrame(data)
        df['date'] = pd.to_datetime(df['date'])
        c = p.line(df['date'], df['close'], line_width=2, color=color, alpha=0.8,
               muted_color=color, muted_alpha=0.2)
        legend_it.append((name, [c]))
    
    
    legend = Legend(items=legend_it)
    legend.click_policy="mute"
    
    p.add_layout(legend, 'right')
    
    show(p)
    

    【讨论】:

    • 经过一些尝试后,我最终得到了与@Despe1990 完全相同的逻辑......这怎么可能是把图例框放在情节框架之外的“最佳”方式?我原以为负位置坐标会成功,但事实并非如此。它只会使输出中的图例消失......这是散景应该出现的东西!
    • 我发现使用 location=(10, 60) 对我来说效果更好。我在列布局中使用我的数字,并且 (0, -60) 使图例部分可见。
    【解决方案2】:

    我想扩展 joelostbloms 的答案。 也可以从现有绘图中提取图例并添加它 情节创建后的其他地方。

    from bokeh.palettes import Category10
    from bokeh.plotting import figure, show
    from bokeh.sampledata.iris import flowers
    
    
    # add a column with colors to the data
    colors = dict(zip(flowers['species'].unique(), Category10[10]))
    flowers["color"] = [colors[species] for species in flowers["species"]]
    
    # make plot
    p = figure(height=350, width=500)
    p.circle("petal_length", "petal_width", source=flowers, legend_group='species',
             color="color")
    p.add_layout(p.legend[0], 'right')
    
    show(p)
    

    【讨论】:

      【解决方案3】:

      也可以将图例放置在绘图区域之外,用于自动分组、间接创建的图例。诀窍是创建一个空图例并使用add_layout 将其放置在绘图区域之外,然后再使用字形legend_group 参数:

      from bokeh.models import CategoricalColorMapper, Legend
      from bokeh.palettes import Category10
      from bokeh.plotting import figure, show
      from bokeh.sampledata.iris import flowers
      
      
      color_mapper = CategoricalColorMapper(
          factors=[x for x in flowers['species'].unique()], palette=Category10[10])
      p = figure(height=350, width=500)
      p.add_layout(Legend(), 'right')
      p.circle("petal_length", "petal_width", source=flowers, legend_group='species',
               color=dict(field='species', transform=color_mapper))
      show(p)
      

      【讨论】:

        【解决方案4】:

        上述答案的可见性说明虽然有用,但没有看到我成功地将图例放置在情节下方,其他人也可能遇到此问题。

        其中 plot_height 或 height 为图形设置如下:

        p = figure(height=400)
        

        但图例是按照 Despee1990 的答案创建的,然后按如下方式放置在图下方:

        legend = Legend(items=legend_it)
        p.add_layout(legend, 'below')
        

        那么图例不显示,情节也不显示。

        如果位置向右改变:

        p.add_layout(legend, 'right')
        

        ...那么图例仅显示在项目适合图形高度的地方。 IE。如果您的绘图高度为 400,但图例需要高度为 800,那么您将看不到不适合绘图区域的项目。

        要解决此问题,可以从图中完全删除绘图高度,或者指定一个足以包含图例项框高度的高度。

        即要么:

        p = figure()
        

        或者如果图例要求的高度 = 800,字形要求的高度是 400:

        p = figure(plot_height=800)
        p.add_layout(legend, 'below')
        

        【讨论】:

          猜你喜欢
          • 2015-11-10
          • 1970-01-01
          • 1970-01-01
          • 2018-06-22
          • 2012-07-10
          相关资源
          最近更新 更多