Hover overling

An empty signal pool is created, a hover is added, at the click of a button the data pool is updated. How to avoid the effect of overlapping hovers?!
hover_aliasing
Test code:

import random
import numpy as np

from bokeh.layouts import column, row
from bokeh.plotting import curdoc, figure
from bokeh.models import  ColumnDataSource, Button, HoverTool

POINTS = 1000
PLOT_WIDTH = 1000
PLOT_HEIGHT = 570

signal_src = {}
signal_figure = figure(plot_height=PLOT_HEIGHT, plot_width=PLOT_WIDTH,
                       tools=["pan,box_zoom,wheel_zoom,save,reset"],
                       x_axis_label='Time', y_axis_label='Amp')
POOL_LEN = 6
pool_data = []
pool_count = 0

# start making pool for signal
for i in range(POOL_LEN):
       color_ = random.choice(('blue', 'red', 'black',
                               'green', 'yellow', 'orange',
                               'pink', 'navy'))
       name_ = f'stage_{i}'
       pool_data.append(ColumnDataSource({'x':[], 'y':[]}))  # Add empty data
       signal_figure.line(x='x', y='y', source=pool_data[i] ,
                                 name=name_, color=color_)
# end
signal_figure.add_tools(HoverTool(tooltips=[('', "$name"), ('', "($x, $y)")]))

def add_callback():
    some_digit = random.randrange(1, 10, step=1)
    name = f'signal{some_digit}'
    # create new data for signal
    signal_src[name] = ColumnDataSource({'x': np.arange(POINTS),
                                         'y': random.randrange(1, 100, step=1) * \
                                              np.sin(2* np.pi * 0.1 * np.arange(POINTS))})
    global pool_count
    if pool_count < POOL_LEN:
        # update data in pool
        pool_data[pool_count].data = {'x': signal_src[name].data['x'],
                                      'y': signal_src[name].data['y']}
        pool_count += 1

add_btn = Button(label="Add", button_type="default")
add_btn.on_click(add_callback)

curdoc().add_root(row(signal_figure, add_btn))

A workaround: python - Displaying only one tooltip when using the HoverTool() tool - Stack Overflow

It didn’t help.
hover_aliasing

import random
import numpy as np

from bokeh.layouts import column, row
from bokeh.plotting import curdoc, figure
from bokeh.models import  ColumnDataSource, Button, HoverTool

POINTS = 1000
PLOT_WIDTH = 1000
PLOT_HEIGHT = 570

signal_src = {}
custom_hover = HoverTool(
    tooltips=
    """
    <style>
        .bk-tooltip>div:not(:first-child) {display:none;}
    </style>
    <b>x: </b> @x <br>
    <b>y: </b> @y <br>
   """)

signal_figure = figure(plot_height=PLOT_HEIGHT, plot_width=PLOT_WIDTH,
                       tools=[custom_hover, "pan,box_zoom,wheel_zoom,save,reset"],
                       x_axis_label='Time', y_axis_label='Amp')
POOL_LEN = 6
pool_data = []
pool_count = 0

# start making pool for signal
for i in range(POOL_LEN):
       color_ = random.choice(('blue', 'red', 'black',
                               'green', 'yellow', 'orange',
                               'pink', 'navy'))
       name_ = f'stage_{i}'
       pool_data.append(ColumnDataSource({'x':[], 'y':[]}))  # Add empty data
       signal_figure.line(x='x', y='y', source=pool_data[i] ,
                                 name=name_, color=color_)
# end



def add_callback():
    some_digit = random.randrange(1, 10, step=1)
    name = f'signal{some_digit}'
    # create new data for signal
    signal_src[name] = ColumnDataSource({'x': np.arange(POINTS),
                                         'y': random.randrange(1, 100, step=1) * \
                                              np.sin(2* np.pi * 0.1 * np.arange(POINTS))})
    global pool_count
    if pool_count < POOL_LEN:
        # update data in pool
        pool_data[pool_count].data = {'x': signal_src[name].data['x'],
                                      'y': signal_src[name].data['y']}
        pool_count += 1

add_btn = Button(label="Add", button_type="default")
add_btn.on_click(add_callback)

curdoc().add_root(row(signal_figure, add_btn))

Probably the markup of the tooltips has changed. Just remove the >div part from the CSS.

Like that ?

custom_hover = HoverTool(
    tooltips=
    """
    <style>
        .bk-tooltip:not(:first-child) {display:none;}
    </style>
    <b>x: </b> @x <br>
    <b>y: </b> @y <br>
   """)

But it don’t solve problem too. Sorry, but i don’t know CSS.

Yep. It worked for me with Bokeh 2.0.2. What version are you using?

I am using Bokeh 2.0.1. and run on Firefox. Please, can you show me your hover ?

import random
import numpy as np

from bokeh.layouts import column, row
from bokeh.plotting import curdoc, figure
from bokeh.models import  ColumnDataSource, Button, HoverTool

POINTS = 1000
PLOT_WIDTH = 1000
PLOT_HEIGHT = 570

signal_src = {}
custom_hover = HoverTool(
    tooltips=
    """
    <style>
        .bk-tooltip:not(:first-child) {display:none;}
    </style>
    <b>x: </b> @x <br>
    <b>y: </b> @y <br>
   """)

signal_figure = figure(plot_height=PLOT_HEIGHT, plot_width=PLOT_WIDTH,
                       tools=["pan,box_zoom,wheel_zoom,save,reset"],
                       x_axis_label='Time', y_axis_label='Amp')
POOL_LEN = 6
pool_data = []
pool_count = 0

# start making pool for signal
for i in range(POOL_LEN):
       color_ = random.choice(('blue', 'red', 'black',
                               'green', 'yellow', 'orange',
                               'pink', 'navy'))
       name_ = f'stage_{i}'
       pool_data.append(ColumnDataSource({'x':[], 'y':[]}))  # Add empty data
       signal_figure.line(x='x', y='y', source=pool_data[i] ,
                                 name=name_, color=color_)
# end

signal_figure.add_tools(custom_hover)


def add_callback():
    some_digit = random.randrange(1, 10, step=1)
    name = f'signal{some_digit}'
    # create new data for signal
    signal_src[name] = ColumnDataSource({'x': np.arange(POINTS),
                                         'y': random.randrange(1, 100, step=1) * \
                                              np.sin(2* np.pi * 0.1 * np.arange(POINTS))})
    global pool_count
    if pool_count < POOL_LEN:
        # update data in pool
        pool_data[pool_count].data = {'x': signal_src[name].data['x'],
                                      'y': signal_src[name].data['y']}
        pool_count += 1

add_btn = Button(label="Add", button_type="default")
add_btn.on_click(add_callback)

curdoc().add_root(row(signal_figure, add_btn))

but after updating i still have problem with bokeh 2.0.2

Here’s what I see:
Screenshot_20200514_171055

Here’s what i see. Bokeh 2.0.2. When i remove ‘>div’ i saw nothing.

custom_hover = HoverTool(
    tooltips=
    """
    <style>
        .bk-tooltip:not(:first-child) {display:none;}
    </style>
    <b>x: </b> @x <br>
    <b>y: </b> @y <br>
   """)

After adding ">div’
hover_overlay

Please, can you tell me. Is it possible or not? Because i still can’t get rid of overlapping

As I already said - it is working for me with the exact same code. I did not really dig it, but it makes it seem like the workaround is very fickle. And unfortunately, I don’t know any other workaround short from writing custom Bokeh models.

Sorry for the obsession, but on your picture you have 2 plots and one hover, not 2 hovers. Yes, it works well, then cursor in the center of the plots for me too :slight_smile:

Instead of displaying several tooltips, I decided to display only “one”.

hover = HoverTool(tooltips=[('', "$name"), ('', "($x, $y)")])
hover.line_policy = 'interp'

It wotk nice.
image