Altair tooltips don't work when using selection

Viewed 778

I am trying to use a vertical rule similar to the one shown on the altair multi-line tooltip example here https://altair-viz.github.io/gallery/multiline_tooltip.html. I would like to use text tooltips too, as my dataset contains text comments that are relevant to each point.

Here is the example code, to which I added a "comments" column with dummy text, and I also added the tooltips to the line component, but the tooltips don't work.

import altair as alt
import pandas as pd
import numpy as np

np.random.seed(42)
source = pd.DataFrame(np.cumsum(np.random.randn(100, 3), 0).round(2),
                    columns=['A', 'B', 'C'], index=pd.RangeIndex(100, name='x'))
source = source.reset_index().melt('x', var_name='category', value_name='y')

I added this line to create a coment column:

source['comments']='comment'+source.category+source.x.apply(str)
# Create a selection that chooses the nearest point & selects based on x-value
nearest = alt.selection(type='single', nearest=True, on='mouseover',
                        fields=['x'], empty='none')

# The basic line 

I added tooltips here:

line = alt.Chart(source).mark_line(interpolate='basis').encode(
    x='x:Q',
    y='y:Q',
    color='category:N',tooltip='comments'
)

And the rest of the code:

# Transparent selectors across the chart. This is what tells us
# the x-value of the cursor
selectors = alt.Chart(source).mark_point().encode(
    x='x:Q',
    opacity=alt.value(0),
).add_selection(
    nearest
)

# Draw points on the line, and highlight based on selection
points = line.mark_point().encode(
    opacity=alt.condition(nearest, alt.value(1), alt.value(0))
)

# Draw text labels near the points, and highlight based on selection
text = line.mark_text(align='left', dx=5, dy=-5).encode(
    text=alt.condition(nearest, 'y:Q', alt.value(' '))
)

# Draw a rule at the location of the selection
rules = alt.Chart(source).mark_rule(color='gray').encode(
    x='x:Q',
).transform_filter(
    nearest
)

# Put the five layers into a chart and bind the data
alt.layer(
    line, selectors, points, rules, text
).properties(
    width=600, height=300
)

If you run this code, it won't show tooltips. To see the tooltips I have to get rid of the selection, so to display the chart at the end and see the tooltips, but not the rule, I would have to do:

alt.layer(line).properties(width=600, height=300)

How can I have both, tooltips and rule?

1 Answers

This is a bug in Vega-Lite; see vega-lite#5732.

To get around it, you can add a selection to each layer that does not already have one; e.g.

text = line.mark_text(align='left', dx=5, dy=-5).encode(
    text=alt.condition(nearest, 'y:Q', alt.value(' '))
).add_selection(alt.selection_single())

Then your tooltip will behave the same whether the layer is shown individually or in the layered chart.

Semi-related note: putting a tooltip on a line chart is probably not what you want (it generates one tooltip per line mark). Try putting your tooltip on the rule mark instead; see Pivot Transform examples for an example of a tooltip like this.

Related