Tooltips in Altair line charts
Asked Answered
P

3

11

When specifying a tooltip for a line chart, the tooltip only appears when hovering over points along a line, but not when hovering anywhere else along a line. This is especially problematic when using a non-linear interpolation... Is there way to explicitly set tooltips on the lines themselves?

import altair as alt
from vega_datasets import data

source = data.jobs.url

alt.Chart(source).mark_line(interpolate="basis").encode(
    alt.X('year:O'),
    alt.Y('perc:Q', axis=alt.Axis(format='%')),
    color='sex:N',
    tooltip='sex:N'
).properties(
    title='Percent of work-force working as Welders'
).transform_filter(
    alt.datum.job == 'Welder'
)

enter image description here

Portent answered 13/11, 2018 at 19:7 Comment(0)
N
7

Extending from @Philipp_Kats's answer and @dominik's comment (and for anyone else who stumbled upon this thread and wish to see the Altair code example), the current way of achieving a "tooltip" effect along the lines is to:

  1. Create the line (mark_line())
  2. Create a selection that chooses the nearest point & selects based on x-value
  3. Snap some transparent selectors across the line, informing the x-value across different positions of the line
  4. Layer (mark_text()) on top of 1 - 3 above

A real example is this line chart on a simple Flask app I made. Only difference was that I didn't make the selectors transparent (opacity=alt.value(0)) but otherwise it's a line chart with tooltips snapped on it.

Here's a reproducible example using OP's original dataset:

# Step 1: create the line
line = alt.Chart().mark_line(interpolate="basis").encode(
    x=alt.X("year:O"),
    y=alt.Y("perc:Q", axis=alt.Axis(format='%')),
    color='sex:N'
).transform_filter(
    alt.datum.job == 'Welder'
)

# Step 2: Selection that chooses nearest point based on value on x-axis
nearest = alt.selection(type='single', nearest=True, on='mouseover',
                            fields=['year'])


# Step 3: Transparent selectors across the chart. This is what tells us
# the x-value of the cursor
selectors = alt.Chart().mark_point().encode(
    x="year:O",
    opacity=alt.value(0),
).add_selection(
    nearest
)

# Step 4: Add text, show values in Sex column when it's the nearest point to 
# mouseover, else show blank
text = line.mark_text(align='left', dx=3, dy=-3).encode(
    text=alt.condition(nearest, 'sex:N', alt.value(' '))
)

# Layer them all together
chart = alt.layer(line, selectors, text, data=source, width=300)

chart

Resulting plot:

enter image description here

Norry answered 16/4, 2019 at 6:22 Comment(0)
R
4

As of March 2022, a workaround for this without complicating your spec too much with selectors and Voronoi tesselation: Use a thick transparent line in the background (opacity should not be exactly 0, because then it is not rendered) and create a layer chart.

base = (
    alt.Chart(
        pd.DataFrame(
            [{"x": 1, "y": 1}, {"x": 2, "y": 2}, {"x": 3, "y": 1}, {"x": 4, "y": 4}]
        )
    )
    .mark_line()
    .encode(x="x:Q", y="y:Q", tooltip="tt:N")
    .transform_calculate(tt="datum.x+' value'")
)
tt = base.mark_line(strokeWidth=30, opacity=0.01)
base + tt
Reconstructive answered 1/3, 2022 at 23:11 Comment(0)
F
3

I doubt that there is a direct technical solution at the moment :-(

One workaround solution is to explicitly add points on top of lines so it is easier to hover. I usually make them relatively large, but hide until the hover event, like here As a cherry on the top, one could use Voronoi to show the closest point at any given point, as they do in this tutorial

Let me know if you need Altair code example, I used raw vega, but implementing Altair version should be relatively trivial

Forefather answered 13/11, 2018 at 22:14 Comment(3)
Vega-Lite author here: yes, this is the preferred approach right now. Tooltips at interpolated positions are problematic because tooltips usually imply some kind of precision but interpolated values are just guesses. So in a way, this is by design. In future versions, we might snap tooltips to the closest defined value.Plenipotentiary
So it looks like tooltips are always associated with points, and there is no concept of tooltips for series (i.e. "colors")?Portent
What do you mean by that?Forefather

© 2022 - 2024 — McMap. All rights reserved.