Search code examples
pythonjupyter-notebookipywidgetsbqplot

bqplot filled Lines blocks tooltip


I'm trying to plot a time series forecast, surrounded by a shaded uncertainty interval timeseries, and have tooltips work for both the line and the perimeter of the uncertainty.

import pandas as pd
from bqplot import *
daterange = pd.date_range(start='2020-01-01', freq='1D', periods=20)
df = pd.DataFrame(index=daterange)
df['fcst'] = np.sin(np.arange(0,20)*2*np.pi / 20)

tt_ex = Tooltip(fields=['x', 'y' ], labels=['', ''], formats=["%B %Y", ',.2f'])

x_sc = DateScale()
y_sc = LinearScale()

fcst_vals = np.arange(0,20)*2*np.pi / 20

x_ax_fcst = Axis(scale=x_sc)
y_ax_fcst = Axis(scale=y_sc, orientation='vertical', tick_format='.2f')


fcst_uncertainty = Lines(x=[daterange.append(daterange[::-1])], 
                         y=[((df['fcst']+0.2).append((df['fcst'][::-1]-0.2)))],
                         fill_colors=['blue'],
                         fill='inside',
                         marker = 'cross',
                         stroke_width=1,
                         close_path=True,
                         scales={'x': x_sc, 'y': y_sc},
                         tooltip=tt_ex)
fcst_uncertainty.fill_opacities = [0.2]

fcst_line = Lines(x=[daterange], y=[df['fcst']],
                  scales={'x': x_sc, 'y': y_sc}, 
                  marker='circle', colors=['blue'],
                  tooltip=tt_ex)

example_fig = Figure(marks=[
    fcst_line,
    fcst_uncertainty
], axes=[x_ax_fcst, y_ax_fcst])

display(example_fig)

But the fill is blocking the tooltip for the main timeseries that is inside of the filled region. Is there any easy way around this? If I remove the fill, it works as desired. But I want the fill. I tried making another Lines object without a tooltip interaction and having that be the filled object, but that didn't work either. Thanks!


Solution

  • You'll kick yourself...reorder the marks in the Figure call to place the uncertainty first, and the line second. The order of the list functions similarly to zorder in matplotlib.

    example_fig = Figure(marks=[
        fcst_uncertainty,
        fcst_line,
    
    ], axes=[x_ax_fcst, y_ax_fcst])
    

    Nice example by the way.