【问题标题】:How to work with ColumnDataSource and LegendItem together in bokeh?如何在散景中同时使用 ColumnDataSource 和 LegendItem?
【发布时间】:2020-04-09 07:11:00
【问题描述】:

我想使用散景创建具有这些函数的分类散点图:

  1. 悬停工具提示

  2. 情节区域外的图例,点击策略=“隐藏”

经过多次搜索,我可以分别实现功能#1和#2。

但我不知道如何让这两个功能同时工作。

工具提示只需要一个字形对象,但绘图区域外的图例需要一个 for 循环来创建用于生成 legend_items 的字形对象列表。 p>

谢谢。

代码示例:

  1. 悬停工具提示可以通过使用 ColumnDataSources 来实现 (https://docs.bokeh.org/en/latest/docs/user_guide/categorical.html#heat-maps)
import pandas as pd
from bokeh.sampledata.stocks import AAPL
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, output_file, show

df = pd.DataFrame(AAPL)
output_file("test.html")
p = figure(tools="hover")
source = ColumnDataSource(df)

p.scatter("high", "low", source=source)

p.hover.tooltips = [("Date","@date")]

show(p)
  1. 剧情外传说 (Position the legend outside the plot area with Bokeh)
import pandas as pd

from bokeh.models import Legend, LegendItem
from bokeh.palettes import Spectral4
from bokeh.plotting import figure, output_file, show
from bokeh.sampledata.stocks import AAPL, GOOG, IBM, MSFT

output_file("test2.html")
p = figure(x_axis_type="datetime")
p_list = []

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'])
    p_list.append(p.line(df['date'], df['close'], line_width=2, color=color, alpha=0.8))

legend_items = [LegendItem(label=x, renderers=[p_list[i]]) for i, x in enumerate(["AAPL", "IBM", "MSFT", "GOOG"])]
legend_ = Legend(items=legend_items, click_policy="hide", location="center", label_text_font_size="12px")
p.add_layout(legend_, "right")

show(p)

【问题讨论】:

  • 您可以将工具添加为实例而不是字符串。 HoverTool 接受 renderersLegendItem 一样。
  • 话虽如此,我仍然不明白为什么不能只将悬停工具添加到第二个示例中。只需在对figure 的调用中指定tools='hover'
  • @EugenePakhomov 感谢您的评论。我不确定工具提示是否可以在不调用 ColumnDataSource 的情况下映射到数据框。我想显示与同一行中的数据相关的特定列。添加 tools='hover' 只是给了我 x、y 和索引的工具提示。
  • 啊,我明白你的意思了。是的,您必须使用ColumnDataSource 才能使用数据列。让我试着举个例子。

标签: python bokeh


【解决方案1】:
import pandas as pd

from bokeh.models import Legend, LegendItem, ColumnDataSource
from bokeh.palettes import Spectral4
from bokeh.plotting import figure, show
from bokeh.sampledata.stocks import AAPL, GOOG, IBM, MSFT

p = figure(x_axis_type="datetime", tools='hover')
p.hover.tooltips = [("Date", "@date{%F}"),
                    ("Open", "@open"),
                    ("Close", "@close")]
p.hover.formatters = {'@date': 'datetime'}

legend_items = []
for data, name, color in zip([AAPL, IBM, MSFT, GOOG],
                             ["AAPL", "IBM", "MSFT", "GOOG"],
                             Spectral4):
    data['date'] = pd.to_datetime(data['date']).values
    ds = ColumnDataSource(data)
    renderer = p.line('date', 'close', source=ds,
                      line_width=2, color=color, alpha=0.8)
    legend_items.append(LegendItem(label=name, renderers=[renderer]))

legend = Legend(items=legend_items, click_policy="hide",
                location="center", label_text_font_size="12px")
p.add_layout(legend, "right")

show(p)

如果您想为不同的股票提供不同的工具提示,您可以为每只股票创建一个悬停工具,并在 tools 参数中指定它们。缺点 - 工具栏上会有多个悬停工具按钮。

【讨论】:

  • 感谢您的评论。这为我提供了一些想法,尽管它不适用于我的情节。我有一个大数据集,所以在使用你的想法后,这些图都变空了。
  • 如果没有浏览器中的实际代码、Python 错误和 JavaScript 错误,就无法说出任何事情。
  • 是的,我明白了。代码和你的差不多,我只是把p.line()改成了p.x()。 DataFrame 的维度是 (700k,6)。通过ColumnDataSource 的for 循环,html 的大小从15MB 增加到了80MB。我只能看到绘图的网格,当我的光标停留在“不可见”点上时,我可以看到正确的工具提示信息。我认为应该是内存不足。
猜你喜欢
  • 1970-01-01
  • 2016-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多