2015-07-18 9 views
22

Ist es möglich, Tooltips zu einem Zeitreihendiagramm hinzuzufügen?Wie füge ich in Bokeh Tooltips zu einem Zeitreihendiagramm (Hover-Tool) hinzu?

Im nachstehenden vereinfachten Codebeispiel möchte ich einen einzelnen Spaltennamen ('a', 'b' oder 'c') sehen, wenn der Mauszeiger über die entsprechende Zeile bewegt wird.

Stattdessen ein "???" wird angezeigt und alle über eine Werkzeugspitze drei Linien bekommen

enter image description here

Per Dokumentation ( http://bokeh.pydata.org/en/latest/docs/user_guide/tools.html#hovertool) (und nicht nur die, die im über schwebt), Feldnamen beginnen mit „@“ als Spalten auf der interpretierte Datenquelle.

  1. Wie kann ich die 'Spalten' aus einem Pandas Datenframe im Tooltip anzeigen?

  2. Oder, wenn die High-Level-TimeSeries-Schnittstelle dies nicht unterstützt, irgendwelche Hinweise für die Verwendung der Schnittstellen der unteren Ebene, um das Gleiche zu tun? (Line? Multi_line?) Oder wandelt die Datenrahmen in ein anderes Format (ColumnDataSource?)

  3. Für Bonusguthaben, wie soll die „$ x“ formated wird das Datum als Datum angezeigt werden?

Dank im Voraus

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) 
+0

Siehe http://stackoverflow.com/questions/31226119/bokeh-hover-tooltip-not-displaying-all-data-ipython-notebook/31234792#31234792 – colinfang

+0

Vielen Dank Colin, das ist wirklich nützlich und gegeben Ich ein paar Hinweise .... wird die Frage aktualisieren oder eine Arbeit zu gegebener Zeit veröffentlichen – bs123

Antwort

8

Unten ist das, was ich mit aufkommen.

Es ist nicht schön, aber es funktioniert.

Ich bin immer noch neu zu Bokeh (& Python für diese Angelegenheit) also, wenn jemand einen besseren Weg vorschlagen möchte, dies zu tun, fühlen Sie sich bitte frei.

enter image description here

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) 
5

Ich bin nicht vertraut mit Pandas, ich benutze Python-Liste nur die sehr Beispiel zu zeigen, wie Tooltips zu muti_lines hinzuzufügen, Seriennamen zeigen und richtig Datum/time.Below Anzeige ist das Ergebnis. Dank @bs123's answer und @tterry's answer in 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

0

Hier ist meine Lösung. Ich habe die Datenquelle für die Glyph-Wiedergabe untersucht, um zu sehen, welche Namen darauf stehen. Dann verwende ich diese Namen auf den Tooltips des Staubsaugers. Sie können das resultierende Diagramm here sehen.

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) 
+0

Netter Anwendungsfall, wie könnte dies verwendet werden, um auf Werte zuzugreifen, die nicht im ursprünglichen Diagramm vorhanden sind? Angenommen, es gibt eine "Beschreibungs" -Spalte, die nicht geplottet wird, aber Sie möchten sie im Tooltip sehen. –