【问题标题】:In Bokeh, how do I add tooltips to a Timeseries chart (hover tool)?在散景中,如何将工具提示添加到时间序列图表(悬停工具)?
【发布时间】:2015-10-08 09:40:11
【问题描述】:

是否可以向时间序列图表添加工具提示?

在下面的简化代码示例中,当鼠标悬停在相关行上时,我希望看到单个列名('a'、'b' 或 'c')。

取而代之的是“???”显示并且所有三行都有一个工具提示(而不仅仅是我悬停在上面的那一行)

根据文档 ( http://docs.bokeh.org/en/latest/docs/user_guide/tools.html#hovertool),以“@”开头的字段名被解释为数据源上的列。

  1. 如何在工具提示中显示来自 pandas DataFrame 的“列”?

  2. 或者,如果高级 TimeSeries 接口不支持这一点,是否有使用低级接口做同样事情的线索? (line?multi_line?)或将DataFrame转换成不同的格式(ColumnDataSource?)

  3. 对于赠金,“$x”应如何格式化以将日期显示为日期?

提前致谢

    import pandas as pd
    import numpy as np
    from bokeh.charts import TimeSeries
    from bokeh.models import HoverTool
    from bokeh.plotting import show

    toy_df = pd.DataFrame(data=np.random.rand(5,3), columns = ('a', 'b' ,'c'), index = pd.DatetimeIndex(start='01-01-2015',periods=5, freq='d'))   

    p = TimeSeries(toy_df, tools='hover')  

    hover = p.select(dict(type=HoverTool))
    hover.tooltips = [
        ("Series", "@columns"),
        ("Date", "$x"),
        ("Value", "$y"),
        ]

    show(p)

【问题讨论】:

标签: python-3.x pandas tooltip bokeh timeserieschart


【解决方案1】:

以下是我想出的。

它不漂亮,但它有效。

我还是 Bokeh 的新手(以及 Python),所以如果有人想提出更好的方法来做到这一点,请随意。

import pandas as pd
import numpy as np
from bokeh.charts import TimeSeries
from bokeh.models import HoverTool
from bokeh.plotting import show

toy_df = pd.DataFrame(data=np.random.rand(5,3), columns = ('a', 'b' ,'c'), index = pd.DatetimeIndex(start='01-01-2015',periods=5, freq='d'))       

 _tools_to_show = 'box_zoom,pan,save,hover,resize,reset,tap,wheel_zoom'        

p = figure(width=1200, height=900, x_axis_type="datetime", tools=_tools_to_show)


# FIRST plot ALL lines (This is a hack to get it working, why can't i pass in a dataframe to multi_line?)   
# It's not pretty but it works. 
# what I want to do!: p.multi_line(df)
ts_list_of_list = []
for i in range(0,len(toy_df.columns)):
    ts_list_of_list.append(toy_df.index.T)

vals_list_of_list = toy_df.values.T.tolist()

# Define colors because otherwise multi_line will use blue for all lines...
cols_to_use =  ['Black', 'Red', 'Lime']
p.multi_line(ts_list_of_list, vals_list_of_list, line_color=cols_to_use)


# THEN put  scatter one at a time on top of each one to get tool tips (HACK! lines with tooltips not yet supported by Bokeh?) 
for (name, series) in toy_df.iteritems():
    # need to repmat the name to be same dimension as index
    name_for_display = np.tile(name, [len(toy_df.index),1])

    source = ColumnDataSource({'x': toy_df.index, 'y': series.values, 'series_name': name_for_display, 'Date': toy_df.index.format()})
    # trouble formating x as datestring, so pre-formating and using an extra column. It's not pretty but it works.

    p.scatter('x', 'y', source = source, fill_alpha=0, line_alpha=0.3, line_color="grey")     

    hover = p.select(dict(type=HoverTool))
    hover.tooltips = [("Series", "@series_name"), ("Date", "@Date"),  ("Value", "@y{0.00%}"),]
    hover.mode = 'mouse'

show(p)

【讨论】:

    【解决方案2】:

    我对 Pandas 不熟悉,我只是使用 python list 来展示如何向 muti_lines 添加工具提示、显示系列名称以及正确显示日期/时间的示例。下面是结果。 感谢@bs123's answer@tterry's answer 中的Bokeh Plotting: Enable tooltips for only some glyphs

    my result

    # -*- coding: utf-8 -*-
    
    from bokeh.plotting import figure, output_file, show, ColumnDataSource
    from bokeh.models import  HoverTool
    from datetime import datetime
    
    dateX_str = ['2016-11-14','2016-11-15','2016-11-16']
    #conver the string of datetime to python  datetime object
    dateX = [datetime.strptime(i, "%Y-%m-%d") for i in dateX_str]
    
    v1= [10,13,5]
    v2 = [8,4,14]
    v3= [14,9,6]
    v = [v1,v2,v3]
    
    names = ['v1','v2','v3']
    colors = ['red','blue','yellow']
    
    output_file('example.html',title = 'example of add tooltips to multi_timeseries')
    tools_to_show = 'hover,box_zoom,pan,save,resize,reset,wheel_zoom'
    p = figure(x_axis_type="datetime", tools=tools_to_show)
    
    #to show the tooltip for multi_lines,you need use the ColumnDataSource which define the data source of glyph
    #the key is to use the same column name for each data source of the glyph
    #so you don't have to add tooltip for each glyph,the tooltip is added to the figure
    
    #plot each timeseries line glyph
    for i in xrange(3):
    # bokeh can't show datetime object in tooltip properly,so we use string instead
        source = ColumnDataSource(data={
                    'dateX': dateX, # python datetime object as X axis
                    'v': v[i],
                    'dateX_str': dateX_str, #string of datetime for display in tooltip
                    'name': [names[i] for n in xrange(3)]
                })
        p.line('dateX', 'v',source=source,legend=names[i],color = colors[i])
        circle = p.circle('dateX', 'v',source=source, fill_color="white", size=8, legend=names[i],color = colors[i])
    
        #to avoid some strange behavior(as shown in the picture at the end), only add the circle glyph to the renders of hover tool
        #so tooltip only takes effect on circle glyph
        p.tools[0].renderers.append(circle)
    
    # show the tooltip
    hover = p.select(dict(type=HoverTool))
    hover.tooltips = [("value", "@v"), ("name", "@name"), ("date", "@dateX_str")]
    hover.mode = 'mouse'
    show(p)
    

    tooltips with some strange behavior,two tips displayed at the same time

    【讨论】:

      【解决方案3】:

      这是我的解决方案。我检查了字形渲染数据源以查看上面的名称。然后我在胡佛工具提示上使用这些名称。你可以看到结果图here

      import numpy as np
      from bokeh.charts import TimeSeries
      from bokeh.models import HoverTool
      from bokeh.plotting import show
      
      toy_df = pd.DataFrame(data=np.random.rand(5,3), columns = ('a', 'b' ,'c'), index = pd.DatetimeIndex(start='01-01-2015',periods=5, freq='d'))   
      #Bockeh display dates as numbers so convert to string tu show correctly
      toy_df.index = toy_df.index.astype(str) 
      p = TimeSeries(toy_df, tools='hover')  
      
      #Next 3 lines are to inspect how are names on gliph to call them with @name on hover
      #glyph_renderers = p.select(dict(type=GlyphRenderer))
      #bar_source = glyph_renderers[0].data_source
      #print(bar_source.data)  #Here we can inspect names to call on hover
      
      
      hover = p.select(dict(type=HoverTool))
      hover.tooltips = [
              ("Series", "@series"),
              ("Date", "@x_values"),
              ("Value", "@y_values"),
              ]
      
      show(p)
      

      【讨论】:

      • 简洁的用例,但是,如何使用它来访问原始图表中不存在的值?例如,假设有一个未绘制的“描述”列,但您希望它出现在工具提示中。
      • 类似的问题,你如何在工具提示中显示值,比如说,存储在 python 列表中而不是散景显示?
      【解决方案4】:

      原始海报的代码不适用于最新的 pandas(DatetimeIndex 构造函数已更改),但 Hovertool 现在支持 formatters 属性,可让您将格式指定为 strftime 字符串。类似的东西

      fig.add_tool(HoverTool(
          tooltip=[
              ('time', '@index{%Y-%m-%d}')
          ],
          formatters={
              '@index': 'datetime'
          }
      ))
      

      【讨论】:

        猜你喜欢
        • 2015-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-29
        相关资源
        最近更新 更多