Text#
text
mark represents each data point with a text instead of a point.
Text Mark Properties#
Click to show code
import altair as alt
import pandas as pd
angle_slider = alt.binding_range(min=-180, max=180, step=1)
angle_var = alt.param(bind=angle_slider, value=0, name="angle")
dx_slider = alt.binding_range(min=-20, max=20, step=1)
dx_var = alt.param(bind=dx_slider, value=5, name="dx")
dy_slider = alt.binding_range(min=-20, max=20, step=1)
dy_var = alt.param(bind=dy_slider, value=0, name="dy")
xOffset_slider = alt.binding_range(min=-20, max=20, step=1)
xOffset_var = alt.param(bind=xOffset_slider, value=0, name="xOffset")
yOffset_slider = alt.binding_range(min=-20, max=20, step=1)
yOffset_var = alt.param(bind=yOffset_slider, value=0, name="yOffset")
fontSize_slider = alt.binding_range(min=1, max=36, step=1)
fontSize_var = alt.param(bind=fontSize_slider, value=14, name="fontSize")
limit_slider = alt.binding_range(min=0, max=150, step=1)
limit_var = alt.param(bind=limit_slider, value=0, name="limit")
align_select = alt.binding_select(options=["left", "center", "right"])
align_var = alt.param(bind=align_select, value="left", name="align")
baseline_select = alt.binding_select(options=["alphabetic", "top", "middle", "bottom"])
baseline_var = alt.param(bind=baseline_select, value="midle", name="baseline")
font_select = alt.binding_select(options=["sans-serif", "serif", "monospace"])
font_var = alt.param(bind=font_select, value="sans-serif", name="font")
fontWeight_select = alt.binding_select(options=["normal", "bold"])
fontWeight_var = alt.param(bind=fontWeight_select, value="normal", name="fontWeight")
fontStyle_select = alt.binding_select(options=["normal", "italic"])
fontStyle_var = alt.param(bind=fontStyle_select, value="normal", name="fontStyle")
source = pd.DataFrame(
{
"a": [30, 25, 70],
"b": [28, 65, 43],
"label": ["Andy", "Brian", "Charlie"],
}
)
base = alt.Chart(source).encode(
x=alt.X("a:Q").axis(labelAngle=0).scale(domain=[0, 100]),
y=alt.Y("b:Q").scale(domain=[0, 100]),
)
pts = base.mark_point()
text = base.mark_text(
dx=dx_var,
dy=dy_var,
xOffset=xOffset_var,
yOffset=yOffset_var,
angle=angle_var,
align=align_var,
baseline=baseline_var,
font=font_var,
fontSize=fontSize_var,
fontStyle=fontStyle_var,
fontWeight=fontWeight_var,
limit=limit_var,
).encode(text="label:N")
(pts + text).add_params(
dx_var,
dy_var,
xOffset_var,
yOffset_var,
angle_var,
align_var,
baseline_var,
font_var,
fontSize_var,
fontStyle_var,
fontWeight_var,
limit_var,
)
A text
mark definition can contain any standard mark properties
and the following special properties:
Click to show table
Property |
Type |
Description |
---|---|---|
angle |
anyOf( |
The rotation angle of the text, in degrees. |
align |
The horizontal alignment of the text or ranged marks (area, bar, image, rect, rule). One of Note: Expression reference is not supported for range marks. |
|
baseline |
anyOf( |
For text marks, the vertical text baseline. One of For range marks, the vertical alignment of the marks. One of Note: Expression reference is not supported for range marks. |
dir |
anyOf( |
The direction of the text. One of Default value: |
dx |
anyOf( |
The horizontal offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the angle property. |
dy |
anyOf( |
The vertical offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the angle property. |
ellipsis |
anyOf( |
The ellipsis string for text truncated in response to the limit parameter. Default value: |
font |
anyOf( |
The typeface to set the text in (e.g., |
fontSize |
anyOf( |
The font size, in pixels. Default value: |
fontStyle |
The font style (e.g., |
|
fontWeight |
anyOf( |
The font weight. This can be either a string (e.g |
limit |
anyOf( |
The maximum length of the text mark in pixels. The text value will be automatically truncated if the rendered size exceeds the limit. Default value: |
lineHeight |
anyOf( |
The line height in pixels (the spacing between subsequent lines of text) for multi-line text marks. |
radius |
anyOf( |
For arc mark, the primary (outer) radius in pixels. For text marks, polar coordinate radial offset, in pixels, of the text from the origin determined by the Default value: |
text |
Placeholder text if the |
|
theta |
anyOf( |
|
Examples#
Text Table Heatmap#
import altair as alt
from vega_datasets import data
source = data.cars()
base = alt.Chart(source).transform_aggregate(
num_cars="count()",
groupby=["Origin", "Cylinders"],
).encode(
alt.X("Cylinders:O").scale(paddingInner=0),
alt.Y("Origin:O").scale(paddingInner=0),
)
heatmap = base.mark_rect().encode(
alt.Color("num_cars:Q")
.scale(scheme="viridis")
.legend(direction="horizontal")
)
predicate = alt.datum.num_cars > 100
text = base.mark_text(baseline="middle").encode(
text="num_cars:Q",
color=alt.when(predicate).then(alt.value("black")).otherwise(alt.value("white")),
)
heatmap + text
Labels#
You can also use text
marks as labels for other marks and set offset (dx
or dy
), align
, and baseline
properties of the mark definition.
import altair as alt
import pandas as pd
source = pd.DataFrame({
"a": ["A", "B", "C"],
"b": [28, 55, 43]
})
bar = alt.Chart(source).mark_bar().encode(
y="a:N",
x=alt.X("b:Q").scale(domain=[0, 60])
)
text = bar.mark_text(
align="left",
baseline="middle",
dx=3
).encode(text="b")
bar + text
Labels Position Based on Condition#
By default, text mark as labels in Altair are positioned above or to the right of the value. However, when dealing with negative values, this default positioning can lead to label overlap with the bar. To address this issue, you can set label positions via Expressions. Here’s an example demonstrating how to do this:
import altair as alt
import pandas as pd
source = pd.DataFrame({
"a": ["A", "B", "C"],
"b": [28, -5, 10]
})
bar = alt.Chart(source).mark_bar().encode(
y="a:N",
x=alt.X("b:Q").scale(domain=[-10, 35])
)
text_conditioned = bar.mark_text(
align="left",
baseline="middle",
dx=alt.expr(alt.expr.if_(alt.datum.b >= 0, 10, -20))
).encode(text="b")
bar + text_conditioned
Scatter Plot with Text#
Mapping a field to text
channel of text mark sets the mark’s text value. For example, we can make a colored scatter plot with text marks showing the initial character of its origin, instead of point
marks.
import altair as alt
from vega_datasets import data
from altair import datum
source = data.cars()
alt.Chart(source).mark_text().encode(
x="Horsepower:Q",
y="Miles_per_Gallon:Q",
color="Origin:N",
text="Origin[0]:N",
)
Geo Text#
By mapping geographic coordinate data to longitude
and latitude
channels of a corresponding projection, we can show text at accurate locations. The example below shows the name of every US state capital at the location of the capital.
import altair as alt
from vega_datasets import data
states = alt.topo_feature(data.us_10m.url, feature="states")
source = data.us_state_capitals()
background = alt.Chart(states).mark_geoshape(
fill="lightgray",
stroke="white",
).properties(
width=750,
height=500,
).project("albersUsa")
line = alt.Chart(source).mark_text(dy=-10).encode(
latitude="lat:Q",
longitude="lon:Q",
text="city:N"
)
point = alt.Chart(source).mark_circle().encode(
latitude="lat:Q",
longitude="lon:Q",
color=alt.value("orange"),
)
background + line + point