Open
Description
What is your suggestion?
This was originally raised on Stack Overflow.
Currently, the documentation lacks an example demonstrating how to add labels to a horizontal bar chart, where the text label appears to the left of the bar when the x
-encoded value is negative and to the right when it’s positive.
The Vega-Lite documentation includes a relevant example: Bar Chart with Negative Values and Labels.
In Vega-Altair, this can be achieved as follows:
import altair as alt
import pandas as pd
# Data
data = pd.DataFrame([
{"a": "A", "b": -28},
{"a": "B", "b": 55},
{"a": "C", "b": -33},
{"a": "D", "b": 91},
{"a": "E", "b": 81},
{"a": "F", "b": 53},
{"a": "G", "b": -19},
{"a": "H", "b": 87},
{"a": "I", "b": 52}
])
# Bar chart
bars = alt.Chart(data).mark_bar().encode(
y=alt.Y("a:N"),
x=alt.X("b:Q").scale(padding=20),
color=alt.when(alt.datum['b'] > 0).then(alt.value("#003865")).otherwise(alt.value("#5E8AB4"))
)
# Text labels
text = alt.Chart(data).mark_text(
align=alt.expr(alt.expr.if_(alt.datum['b'] < 0, 'right', 'left')),
dx=alt.expr(alt.expr.if_(alt.datum['b'] < 0, -2, 2))
).encode(
y="a:N",
x="b:Q",
text="b:Q"
)
bars + text

Side note: I'm not a fan of this syntax:
alt.expr(alt.expr.if_(alt.datum['b'] < 0, 'right', 'left'))`
Maybe we can introduce a more intuitive alternative for mark property expressions, similar to how we handle encoding channel selection parameters?
alt.expr.when(alt.datum['b'] < 0).then('right').otherwise('left')`