Tooltips in Altair line charts

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?

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

3 Answers

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:

  • Create the line (mark_line())
  • Create a selection that chooses the nearest point & selects based on x-value
  • Snap some transparent selectors across the line, informing the x-value across different positions of the line
  • 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

    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 

    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

    3

    ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJobGxqaGyGc4SOraaopKSevbR5yKdkmqSklrazecuipZ5lk52us8DS

     Share!