user7346517
user7346517

Reputation: 25

Bokeh / Python issue with TOOLTIPS / Hover over

enter image description hereNeed help with below code, my hover over is not showing any data just ???. Im guessing its because I havent defined the source properly or I need to include an argument in the vbar code. Do I need to add more info to the source e.g. column names etc or do I also need to refer to the source and column names in the vbar arguments?

Thanks

def get_width():
    mindate = df['local_time'].min()
    maxdate = df['local_time'].max()
    return 0.8 * (maxdate-mindate).total_seconds()*1000 / len(df['local_time'])

plots = []
sliders = []

for t in df['timeframeID'].unique():

    inc = df[df['timeframeID'] == t].close > df[df['timeframeID'] == t].open
    dec = df[df['timeframeID'] == t].open > df[df['timeframeID'] == t].close

source = ColumnDataSource(data=df)

TOOLS = "pan,wheel_zoom,box_zoom,crosshair,reset,save"

TOOLTIPS = [('open', '@open'),('high', '@high'),('low', '@low'),('close', '@close')]

name1= figure(plot_width=1600, plot_height = 900, title="Instrument AUDUSD: "+t, tools = TOOLS, tooltips=TOOLTIPS)
name1.xaxis.major_label_overrides = {
i: date.strftime('%b %d') for i, date in enumerate(pd.to_datetime(df["local_time"]))
}
name1.xaxis.bounds = (0, df.index[-1])

name1.segment(df[df['timeframeID'] == t].index[inc], df[df['timeframeID'] == t].high[inc],
              df[df['timeframeID'] == t].index[inc],df[df['timeframeID'] == t].low[inc], color="black")
name1.segment(df[df['timeframeID'] == t].index[dec], df[df['timeframeID'] == t].high[dec],
              df[df['timeframeID'] == t].index[dec],df[df['timeframeID'] == t].low[dec], color="black")
#name1.y_range.range_padding = 0.05
name1.vbar(df[df['timeframeID']== t].index[inc], 0.5, df[df['timeframeID']== t].open[inc], df[df['timeframeID']== t].close[inc],
fill_color="green", line_color="green")#, width=get_width())
name1.vbar(df[df['timeframeID']== t].index[dec], 0.5, df[df['timeframeID']== t].open[dec], df[df['timeframeID']== t].close[dec],
fill_color="#F2583E", line_color="#F2583E")#, width=get_width())

r = name1.circle(df[df['timeframeID']== t].index, df[df['timeframeID']== t].AV, alpha = 1, radius = .20)
name1.y_range.range_padding = 0.05

callback = CustomJS(args=dict(renderer=r), code="""
renderer.glyph.radius = cb_obj.value;
""")

s = Slider(start=0, end=1.5, value=.20, step=.05, title="Radius - " + t)
s.js_on_change('value', callback)

output_notebook()


output_file("candlestick.html", title="candlestick.py example")

sliders.append(s)
plots.append(name1)

show(column(
row(
*plots),*sliders))

Here is what my dataframe, df, looks like: enter image description here

Upvotes: 0

Views: 248

Answers (1)

syntonym
syntonym

Reputation: 7384

Currently you are directly providing data only for the x and y coordinate. Bokeh does not know anything about the other data. To make bokeh aware of all the data you must pass a source via source=source in your vbar method. When you pass the source, bokeh gets all the data so that it can look at different columns to show when hovering.

When you pass a source, you cannot pass the x, top and bottom coordinates directly, because otherwise bokeh would not know how to associate these values to the source you passed¹. So when you pass a source, you want to pass the names of the x, top and bottom coordinate columns, instead of the data directly. So you want to write something like:

name1.vbar("index", "open", "close", source=source, fill_color="green", line_color="green")

To do this you need to construct a source/DataFrame which already has the data you want, instead of doing the filtering you are doing in the vbar call. Without seeing your data I cannot tell you how you would construct such a Dataframe though.

1: Actually bokeh associates directly passed data via the index, so the first value is associated with the first line in the source.

Upvotes: 1

Related Questions