如何将HoverTool添加到数据表(Bokeh,Python)

时间:2015-12-09 01:33:09

标签: python plot bokeh

我正在尝试bokeh data table。是否可以在散景表中的每个字段中添加HoverTool

DataTable的一个例子 - enter image description here

以及HoverTool如何运作的例子 - enter image description here

2 个答案:

答案 0 :(得分:9)

使用HTMLTemplateFormatter

可以实现

<强> main.py

from os.path import dirname, join
import pandas as pd
from bokeh.io import curdoc, show
from bokeh.models import ColumnDataSource, Div
from bokeh.models.widgets import DataTable, TableColumn, HTMLTemplateFormatter
from bokeh.layouts import layout

template = """<span href="#" data-toggle="tooltip" title="<%= value %>"><%= value %></span>"""

df = pd.DataFrame([
    ['this is a longer text that needs a tooltip, because otherwise we do not see the whole text', 'this is a short text'],
    ['this is another loooooooooooooooong text that needs a tooltip', 'not much here'],
], columns=['a', 'b'])

columns = [TableColumn(field=c, title=c, width=20, formatter=HTMLTemplateFormatter(template=template)) for c in ['a', 'b']]

table = DataTable(source=ColumnDataSource(df), columns=columns)

l = layout([[table]])

curdoc().add_root(l)

show(l)

enter image description here

一种稍微好一点的方式(虽然有点痛苦)会使用不同的模板和一些CSS样式。

template = """<div class="tooltip-parent"><div class="tooltipped"><%= value %></div><div class="tooltip-text"><%= value %></div></div>"""

<强> desc.html

<style>
.tooltip-parent {
    width: 100%;
}

.tooltipped {
    overflow: hidden;
    width: 100%;
}

.tooltip-text {
    visibility: hidden;
    width: 250px;
    background-color: rgba(0, 0, 0, 1);
    color: #fff;
    text-align: center;
    border-radius: 6px;
    padding: 5px 5px;
    position: relative;
    z-index: 1;
    top: 100%;
    left: 0%;
    white-space: initial;
    text-align: left;
}

.tooltipped:hover + .tooltip-text {
    visibility: visible;
}

div.bk-slick-cell {
    overflow: visible !important;
    z-index: auto !important;
}
</style>

<h1>Tooltip demo</h1>

enter image description here

答案 1 :(得分:2)

尝试将pandas DataFrame转换为html,然后在调用时使用自定义散景工具提示中的{safe}标记。我得到了下面的例子来运行最新的散景(built from the github,但它应该稍后通过pip可用)。

import datetime
import numpy as np
import pandas as pd

from bokeh.io import show, output_notebook
from bokeh.plotting import ColumnDataSource, figure
from bokeh.models import HoverTool, Range1d

# Create dataframe of dates and random download numbers.
startdate = datetime.datetime.now()
nextdate = lambda x:startdate+datetime.timedelta(x)

value = 10

dates = [nextdate(i) for i in range(value)]
downloads = np.random.randint(0,1000,value)
data = np.array([dates,downloads]).T
data = pd.DataFrame(data,columns = ["Date","Downloads"])
data["Date"] = data.Date.apply(lambda x:"{:%Y %b %d}".format(x))

# Convert dataframe to html
data_html = data.to_html(index=False)

output_notebook()

fig = figure(x_range=(0, 5), y_range=(0, 5),tools=[HoverTool(tooltips="""@html{safe}""")])

source=ColumnDataSource(data=dict(x=[1,3],
                                  y=[2,4],
                                  html=["<b>Some other html.</b>", data_html]))

fig.circle('x', 'y', size=20, source=source)

show(fig)

如果你想要一个你可以更容易在这里设置样式的表是一个使用dominate html生成包的例子:

import datetime
import numpy as np
import pandas as pd
from dominate.tags import *

%env BOKEH_RESOURCES=inline
from collections import OrderedDict
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, HoverTool, TapTool, OpenURL
# For displaying in jupyter notebook
from bokeh.io import push_notebook,show,output_notebook
from bokeh.resources import INLINE
output_notebook(resources=INLINE)

# Create dataframe of dates and random download numbers.
startdate = datetime.datetime.now()
nextdate = lambda x:startdate+datetime.timedelta(x)

value = 5

dates = [nextdate(i) for i in range(value)]
downloads = np.random.randint(0,1000,value)
data = np.array([dates,downloads]).T
data = pd.DataFrame(data,columns = ["Date","Downloads"])
data["Date"] = data.Date.apply(lambda x:"{:%Y %b %d}".format(x))

# STYLES
header_style = ["border:1px solid black",
                "font-size:10px",
                "font-weight:bold",
                "color:black",
                "padding:3px",
               ]

header_style = ";".join(header_style)+";"

td_style = ["border: 1px solid black",
            "font-size:10px",
            "padding:3px",]

td_style = ";".join(td_style)+";"

# Create HTML table
my_table = table()
my_table.add(tr([th(i,style=header_style) for i in data.columns]))

[my_table.add(tr([td("{}".format(j),style=td_style) for j in i])) for i in data.values]

# Create figure
fig = figure(x_range=(0, 5), y_range=(0, 5),tools=[HoverTool(tooltips="""@html{safe}""")])

source=ColumnDataSource(data=dict(x=[1,3],
                                  y=[2,4],
                                  html=["<b>Some other html.</b>", my_table.render()]))

fig.circle('x', 'y', size=20, source=source)

show(fig)