文本#

text 标记用文本而不是点来表示每个数据点。

文本标记属性#

点击显示代码
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,
)

一个 text 标记定义可以包含任何 标准标记属性 以及以下特殊属性

点击显示表格

属性

类型

描述

angle

anyOf(number, ExprRef)

文本的旋转角度,单位为度。

align

anyOf(Align, ExprRef)

文本或范围标记(面积图、条形图、图像、矩形、直线)的水平对齐方式。可选值包括 "left""right""center"

注意:范围标记支持表达式引用。

baseline

anyOf(TextBaseline, ExprRef)

对于文本标记,垂直文本基线。可选值包括 "alphabetic"(默认)、 "top""middle""bottom""line-top""line-bottom",或提供有效值的表达式引用。"line-top""line-bottom" 的作用类似于 "top""bottom",但它们是相对于 lineHeight 计算的,而不是单独相对于 fontSize 计算。

对于范围标记,标记的垂直对齐方式。可选值包括 "top""middle""bottom"

注意:范围标记支持表达式引用。

dir

anyOf(TextDirection, ExprRef)

文本方向。可选值包括 "ltr"(从左到右)或 "rtl"(从右到左)。此属性决定了文本在响应 limit 参数时从哪一侧截断。

默认值: "ltr"

dx

anyOf(number, ExprRef)

文本标签与其锚点之间的水平偏移量,单位为像素。此偏移量在应用 angle 属性旋转后计算。

dy

anyOf(number, ExprRef)

文本标签与其锚点之间的垂直偏移量,单位为像素。此偏移量在应用 angle 属性旋转后计算。

ellipsis

anyOf(string, ExprRef)

文本在响应 limit 参数被截断时使用的省略号字符串。

默认值: "…"

font

anyOf(string, ExprRef)

设置文本的字体(例如,"Helvetica Neue")。

fontSize

anyOf(number, ExprRef)

字体大小,单位为像素。

默认值: 11

fontStyle

anyOf(FontStyle, ExprRef)

字体样式(例如,"italic")。

fontWeight

anyOf(FontWeight, ExprRef)

字体粗细。可以是字符串(例如 "bold""normal"),也可以是数字(100200300、 …、 900,其中 "normal" = 400"bold" = 700)。

limit

anyOf(number, ExprRef)

文本标记的最大长度,单位为像素。如果渲染尺寸超出此限制,文本值将自动截断。

默认值: 0 – 表示无限制

lineHeight

anyOf(number, ExprRef)

多行文本标记的行高,单位为像素(即文本后续行之间的间距)。

radius

anyOf(number, ExprRef)

对于圆弧标记,主(外)半径,单位为像素。

对于文本标记,文本相对于由 xy 属性确定的原点的极坐标径向偏移量,单位为像素。

默认值: min(plot_width, plot_height)/2

text

anyOf(Text, ExprRef)

如果未指定 text 通道,则使用的占位符文本

theta

anyOf(number, ExprRef)

  • 对于圆弧标记,如果未指定 theta2,则为弧长(单位弧度),否则为起始弧角。(值为 0 表示向上或“北方”,数值增大表示顺时针方向。)

  • 对于文本标记,极坐标角度,单位为弧度。

示例#

文本表格热力图#

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

标签#

您还可以使用 text 标记作为其他标记的标签,并设置标记定义的偏移量(dxdy)、alignbaseline 属性。

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

基于条件的标签位置#

默认情况下,Altair 中的文本标记标签位于数值上方或右侧。然而,当处理负值时,这种默认位置可能导致标签与条形重叠。为了解决这个问题,您可以通过 表达式 设置标签位置。以下是一个演示如何操作的示例

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

带有文本的散点图#

将字段映射到文本标记的 text 通道会设置标记的文本值。例如,我们可以创建一个彩色散点图,使用文本标记显示来源的首字母,而不是 point 标记。

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",
)

地理文本#

通过将地理坐标数据映射到相应投影的 longitudelatitude 通道,我们可以在准确位置显示文本。下面的示例在每个美国州府所在地显示了州府名称。

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