How do you get a tool tip on Bokeh candlestick chart like this:
or/and a lable like this:
The code I have so far for drawing the chart is as follows:
import pandas as pd import numpy as np from bokeh.plotting import figure, output_notebook, show from bokeh.models import LinearAxis, Range1d, Segment, Legend from bokeh.models.formatters import NumeralTickFormatter, DatetimeTickFormatter from bokeh.palettes import Category20 output_notebook() def init_chart(name): # Tools Selections: TOOLS = "pan,xwheel_zoom,box_zoom,crosshair,undo,redo,reset,save" p = figure(x_axis_type="datetime", tools=TOOLS, title = name) p.add_layout(Legend(click_policy="hide", orientation='horizontal', spacing=20), 'below') p.sizing_mode = 'scale_both' return p def init_price_volume_chart(p, df): RED = Category20[7][6] GREEN = Category20[5][4] inc = df.Close > df.Open dec = df.Open > df.Close w = 12*60*60*1000 # half day in ms p.x_range = Range1d(df.index[0], df.index[-1]) p.xaxis[0].formatter = DatetimeTickFormatter(months="%b %Y", days="%d %b %Y") p.xaxis.axis_label = 'Date' p.xaxis.major_label_orientation = 3.1415/4 p.xaxis.ticker.desired_num_ticks = 40 # left y axis low, high = df.Low.min(), df.High.max() p.y_range = Range1d(low * 0.9, high * 1.1) p.yaxis.axis_label = 'Price' p.yaxis[0].formatter = NumeralTickFormatter(format="0,0.00") p.segment(df.index, df.High, df.index, df.Low, color=GREEN, legend_label='Candlestick') p.vbar(df.index[inc], w, df.Open[inc], df.Close[inc], fill_color=GREEN, line_color=GREEN, legend_label='Candlestick') p.vbar(df.index[dec], w, df.Open[dec], df.Close[dec], fill_color=RED, line_color=RED, legend_label='Candlestick') # right y axis p.extra_y_ranges.update({'two': Range1d(0, 1.1*df.Volume.max())}) p.add_layout(LinearAxis(y_range_name='two', axis_label='Volume' ), 'right') p.yaxis[1].formatter = NumeralTickFormatter(format="0a") p.vbar(df.index[inc], w, df.Volume[inc], [0]*inc.sum(), alpha=0.5, level='underlay', fill_color=GREEN, line_color=GREEN, legend_label='Volume', y_range_name='two') p.vbar(df.index[dec], w, df.Volume[dec], [0]*dec.sum(), alpha=0.5, level='underlay', fill_color=RED, line_color=RED, legend_label='Volume', y_range_name='two') return p
Advertisement
Answer
Your Bokeh Candlesticks consists of two glyphs: vbar
and segment
. In the code below there is only a tooltip on the vbar
but you could add it also to the segment
(code made for Bokeh v2.1.1) I also left out irrelevant code to make the code look simpler.
import pandas as pd from bokeh.plotting import figure, output_notebook, show from bokeh.models import Legend, HoverTool, ColumnDataSource from bokeh.palettes import Category20 from datetime import datetime, timedelta output_notebook() df = pd.DataFrame({"index": [datetime(2017,1,1) + timedelta(days=x) for x in range(0,3)], "Open": [3, 2, 3], "Low": [2, 0.5, 2.5], "High": [5, 3, 4.5], "Close": [4, 1, 4.5], "Volume": [10000, 20000, 10000]}) df_red = df.loc[(df['Open'] >= df['Close'])] df_green = df.loc[(df['Close'] >= df['Open'])] source = ColumnDataSource(df) source_red = ColumnDataSource(df_red) source_green = ColumnDataSource(df_green) RED = Category20[7][6] GREEN = Category20[5][4] w = 12*60*60*1000 def init_chart(name): # Tools Selections: TOOLS = "pan,xwheel_zoom,box_zoom,crosshair,undo,redo,reset,save" p = figure(x_axis_type="datetime", tools=TOOLS, title = name, plot_width = 1200, plot_height=500) p.add_layout(Legend(click_policy="hide", orientation='horizontal', spacing=20), 'below') p.sizing_mode = 'scale_both' return p p = init_chart('Plot1') segmnts_green = p.segment('index', 'High', 'index', 'Low', color=GREEN, source=source_green, legend_label='Up') segmnts_red = p.segment('index', 'High', 'index', 'Low', color=RED, source=source_red, legend_label='Down') vbars_green = p.vbar('index', w, 'Open', 'Close', source=source_green, fill_color=GREEN, line_color=GREEN, legend_label='Up') vbars_red = p.vbar('index', w, 'Close', 'Open', source=source_red, fill_color=RED, line_color=RED, legend_label='Down') tooltips=[('open', '@Open'),('close', '@Close'), ('low', '@Low'), ('high', '@High')] red_hover = HoverTool(renderers=[vbars_red], tooltips=tooltips) p.add_tools(red_hover) green_hover = HoverTool(renderers=[vbars_green], tooltips=tooltips) p.add_tools(green_hover) show(p)