线图#
line
标记表示存储在字段中的数据点,并用一条线连接所有这些点。线标记通常用于描绘轨迹或随时间的变化。与大多数表示每个标记一个数据元素的其他标记不同,一个线标记将多个数据元素表示为一条单独的线,类似于area
和trail
。
注意:对于连接 (x,y) 位置到 (x2,y2) 位置的线段,请使用rule
标记。对于大小连续变化的线条,请使用trail
标记。
线标记属性#
点击显示代码
import altair as alt
import pandas as pd
interpolate_select = alt.binding_select(
options=[
"basis",
"basis-open",
"basis-closed",
"bundle",
"cardinal",
"cardinal-open",
"cardinal-closed",
"catmull-rom",
"linear",
"linear-closed",
"monotone",
"natural",
"step",
"step-before",
"step-after",
],
name="interpolate",
)
interpolate_var = alt.param(bind=interpolate_select, value="linear")
tension_slider = alt.binding_range(min=0, max=1, step=0.05, name="tension")
tension_var = alt.param(bind=tension_slider, value=0)
strokeWidth_slider = alt.binding_range(min=0, max=10, step=0.5, name="strokeWidth")
strokeWidth_var = alt.param(bind=strokeWidth_slider, value=2)
strokeCap_select = alt.binding_select(
options=["butt", "round", "square"],
name="strokeCap",
)
strokeCap_var = alt.param(bind=strokeCap_select, value="butt")
strokeDash_select = alt.binding_select(
options=[[1, 0], [8, 8], [8, 4], [4, 4], [4, 2], [2, 1], [1, 1]],
name="strokeDash",
)
strokeDash_var = alt.param(bind=strokeDash_select, value=[1, 0])
source = pd.DataFrame({"u": [1, 2, 3, 4, 5, 6], "v": [28, 55, 42, 34, 36, 38]})
alt.Chart(source).mark_line(
interpolate=interpolate_var,
tension=tension_var,
strokeWidth=strokeWidth_var,
strokeCap=strokeCap_var,
strokeDash=strokeDash_var,
).encode(x="u", y="v").add_params(
interpolate_var, tension_var, strokeWidth_var, strokeCap_var, strokeDash_var
)
一个line
标记定义可以包含任何标准标记属性以及以下线条插值和点覆盖属性
点击显示表格
属性 |
类型 |
描述 |
---|---|---|
orient |
非堆叠条形图、刻度图、面积图和线图的方向。取值为 horizontal(水平,默认)或 vertical(垂直)。
|
|
interpolate |
anyOf( |
用于线和面积标记的线条插值方法。以下之一
|
tension |
anyOf( |
根据插值类型,设置张力参数(用于线和面积标记)。 |
point |
anyOf( |
一个标志,用于在线或面积标记之上叠加点,或者一个定义叠加点属性的对象。
**默认值:** |
示例#
线图#
使用一个时间或顺序字段(通常在x
轴上)和另一个定量字段(通常在y
轴上)与 line 标记结合,可以生成一个简单的单线条图。
import altair as alt
from altair import datum
from vega_datasets import data
source = data.stocks()
alt.Chart(source).mark_line().encode(
x="date",
y="price",
).transform_filter(datum.symbol == "GOOG")
我们可以通过沿着不同的属性(如color
或detail
)进行分组来创建多条线。
多系列彩色线图#
将一个字段添加到标记属性通道(如color
)可以将数据点分组到不同的系列中,生成多系列彩色线图。
import altair as alt
from vega_datasets import data
source = data.stocks()
alt.Chart(source).mark_line().encode(
x="date",
y="price",
color="symbol",
)
我们可以进一步应用选择,以便在悬停时突出显示某条线。
import altair as alt
from vega_datasets import data
source = data.stocks()
highlight = alt.selection_point(
on="pointerover", fields=["symbol"], nearest=True
)
base = alt.Chart(source).encode(
x="date:T",
y="price:Q",
color="symbol:N"
)
points = base.mark_circle().encode(
opacity=alt.value(0)
).add_params(
highlight
).properties(
width=600
)
lines = base.mark_line().encode(
size=alt.when(~highlight).then(alt.value(1)).otherwise(alt.value(3))
)
points + lines
使用不同虚线的的多系列线图#
将一个字段添加到strokeDash
也会生成多系列线图。
import altair as alt
from vega_datasets import data
source = data.stocks()
alt.Chart(source).mark_line().encode(
x="date",
y="price",
strokeDash="symbol",
)
我们还可以使用线条分组来创建具有不同样式部分的线图。
import altair as alt
import pandas as pd
source = pd.DataFrame({
"a": ["A", "B", "D", "E", "E", "G", "H"],
"b": [28, 55, 91, 81, 81, 19, 87],
"predicted": [False, False, False, False, True, True, True]
})
alt.Chart(source).mark_line().encode(
x="a:O",
y="b:Q",
strokeDash="predicted:N"
)
使用 Detail 通道的多系列线图#
为了通过一个字段对线条进行分组,而无需将该字段映射到任何视觉属性,我们可以将该字段映射到detail
通道,以创建具有相同颜色的多系列线图。
import altair as alt
from vega_datasets import data
source = data.stocks()
alt.Chart(source).mark_line().encode(
x="date",
y="price",
detail="symbol",
)
同样的方法可用于为范围点图分组线条。
import altair as alt
from vega_datasets import data
source = data.countries()
base = alt.Chart(source).encode(
alt.X("life_expect:Q")
.scale(zero=False)
.title("Life Expectancy (years)"),
alt.Y("country:N")
.axis(offset=5, ticks=False, minExtent=70, domain=False)
.title("Country")
).transform_filter(
alt.FieldOneOfPredicate(field="country", oneOf=["China", "India", "United States", "Indonesia", "Brazil"])
)
line = base.mark_line().encode(
detail="country",
color=alt.value("#db646f")
).transform_filter(
alt.FieldOneOfPredicate(field="year", oneOf=[1995, 2000])
)
point = base.mark_point(filled=True).encode(
alt.Color("year").scale(range=["#e6959c", "#911a24"], domain=[1995, 2000]),
size=alt.value(100),
opacity=alt.value(1),
)
line + point
带有标记点的线图#
通过将标记定义的point
属性设置为True
或定义叠加点标记属性的对象,我们可以在线条上方叠加点标记。
import altair as alt
from vega_datasets import data
source = data.stocks()
alt.Chart(source).mark_line(point=True).encode(
x="year(date)",
y="mean(price):Q",
color="symbol:N"
)
这等同于添加另一层实心点标记。
请注意,叠加点标记默认为opacity
= 1(而不是像普通点标记那样半透明)。
这里我们通过将filled
设置为False
并将fill
设置为"white"
来创建带描边的点。
import altair as alt
from vega_datasets import data
source = data.stocks()
alt.Chart(source).mark_line(
point=alt.OverlayMarkDef(filled=False, fill="white")
).encode(
x="year(date)",
y="mean(price):Q",
color="symbol:N"
)
自定义排序#
默认情况下,线的路径(线中点的顺序)由时间/顺序字段上的数据值决定。但是,可以将一个字段映射到order
通道来确定自定义路径。
例如,为了显示汽油价格和人均行驶里程随时间的数据变化模式,我们使用order
通道按年份字段对线条中的点进行排序。在此示例中,我们还使用point
属性在线条标记上叠加点标记,以突出显示每个数据点。现在,最早的数据点(1956)是线条的一个端点,而最新的数据点(2010)是线条的另一个端点。
import altair as alt
from vega_datasets import data
source = data.driving()
alt.Chart(source).mark_line(point=True).encode(
alt.X("miles").scale(zero=False),
alt.Y("gas").scale(zero=False),
order="year",
tooltip=["miles", "gas", "year"],
)
线条插值#
标记定义的interpolate
属性可用于更改线条插值方法。例如,我们可以将interpolate
设置为"monotone"
。
import altair as alt
from vega_datasets import data
source = data.stocks()
alt.Chart(source).mark_line(interpolate="monotone").encode(
x="date",
y="price",
).transform_filter(
alt.datum.symbol == "GOOG"
)
我们还可以将interpolate
设置为"step-after"
来创建阶梯图。
import altair as alt
from vega_datasets import data
source = data.stocks()
alt.Chart(source).mark_line(interpolate="step-after").encode(
x="date",
y="price"
).transform_filter(
alt.datum.symbol == "GOOG"
)
地理线图#
通过将地理坐标数据映射到相应投影的longitude
和latitude
通道,我们可以绘制穿过地理点的线条。
import altair as alt
from vega_datasets import data
import pandas as pd
airports = data.airports.url
flights_airport = data.flights_airport.url
states = alt.topo_feature(data.us_10m.url, feature="states")
lookup_data = alt.LookupData(
airports, key="iata", fields=["state", "latitude", "longitude"]
)
source = pd.DataFrame({
"airport": ["SEA", "SFO", "LAX", "LAS", "DFW", "DEN", "ORD", "JFK"],
"order": [1, 2, 3, 4, 5, 6, 7, 8],
})
background = alt.Chart(states).mark_geoshape(
fill="lightgray",
stroke="white"
).properties(
width=750,
height=500,
).project("albersUsa")
line = alt.Chart(source).mark_line().encode(
latitude="latitude:Q",
longitude="longitude:Q",
order="order"
).transform_lookup(
lookup="airport",
from_=lookup_data
)
background + line