Search code examples
python-3.xdata-visualizationaltairvega-lite

Display value as text, of only the bar with the maximum height in altair


I am not able to do this seemingly simple task of displaying the value of only the maximum bar over the bar itself - like annotating the maximum bar.

For the code below I'd like to see the text only over the bar with the value 16.

data = pd.DataFrame({'time':[0,1,2,3,4,5,6,7,8,9], 'value':[1,2,4,8,16,11,9,7,5,3]})

bar = alt.Chart(data).mark_bar(opacity=1, width=15).encode(
    x='time:T',
    y='value:Q',
    color = alt.condition(alt.datum.time>7, alt.value('red'), alt.value('steelblue')) #hackey way to highlight last 'n' bars 
)

text = bar.mark_text(align='center', dy=-10).encode(
    text='value:Q'
)

bar+text

I tried using some transforms and using argmax and max but nothing seems to work so far. Either all of them display the value or all is Null.


Solution

  • You can do this using an argmax aggregate in the x and y encodings:

    import altair as alt
    import pandas as pd
    
    data = pd.DataFrame({'time':[0,1,2,3,4,5,6,7,8,9], 'value':[1,2,4,8,16,11,9,7,5,3]})
    
    bar = alt.Chart(data).mark_bar(opacity=1, width=15).encode(
        x='time:T',
        y='value:Q',
        color = alt.condition(alt.datum.time>7, alt.value('red'), alt.value('steelblue')) #hackey way to highlight last 'n' bars 
    )
    
    text = bar.mark_text(align='center', dy=-10).encode(
        x=alt.X('time:T', aggregate={"argmax": "value"}),
        y=alt.Y('value:Q', aggregate={"argmax": "value"}),
        text='max(value):Q'
    )
    
    bar+text
    

    enter image description here