Линейные отрезки — Rule
Примитив rule представляет каждую точку данных отрезком. Он может занимать всю ширину или высоту представления либо соединять две заданные позиции.
Свойства отрезков
Определение rule поддерживает любые стандартные свойства.
Примеры
Линии на всю ширину или высоту
Если у rule задан только канал y, линии горизонтальны и занимают всю ширину. Если задан только x, линии вертикальны и занимают всю высоту.
Например, покажем среднюю цену акций разных компаний, подобно коротким чертам tick:
import altair as alt
from altair.datasets import data
source = data.stocks()
alt.Chart(source).mark_rule().encode(
y="mean(price):Q",
size=alt.value(2),
color="symbol:N"
)
Способность занимать всю ширину или высоту делает rule удобным слоем аннотаций. Например, покажем средние цены акций вместе с кривыми цен:
import altair as alt
from altair.datasets import data
source = data.stocks()
base = alt.Chart(source).properties(width=550)
line = base.mark_line().encode(
x="date",
y="price",
color="symbol"
)
rule = base.mark_rule().encode(
y="average(price)",
color="symbol",
size=alt.value(2)
)
line + rule
Можно также показать общее среднее поверх гистограммы:
import altair as alt
from altair.datasets import data
source = data.movies.url
base = alt.Chart(source)
bar = base.mark_bar().encode(
x=alt.X("IMDB Rating:Q").bin().axis(None),
y="count()"
)
rule = base.mark_rule(color="red").encode(
x="mean(IMDB Rating):Q",
size=alt.value(5),
)
bar + rule
Отрезки с заданными границами
Длину горизонтальных и вертикальных отрезков задают каналы x и x2 либо y и y2.
Например, через y и y2 покажем минимальную и максимальную мощность автомобилей разных регионов происхождения:
import altair as alt
from altair.datasets import data
source = data.cars()
alt.Chart(source).mark_rule().encode(
x="Origin",
y="min(Horsepower)",
y2="max(Horsepower)",
)
Диагональная линия
С помощью alt.value и специальных сигналов 'width' и 'height' можно провести диагональ от угла до угла независимо от диапазонов x и y. Линия рисуется в пространстве пикселей:
import altair as alt
from altair.datasets import data
source = data.cars()
points = alt.Chart(source).mark_circle(size=60).encode(
x=alt.X("Horsepower:Q"),
y=alt.Y("Miles_per_Gallon:Q"),
)
diagonal = alt.Chart().mark_rule(strokeDash=[4, 4]).encode(
x=alt.value(0),
y=alt.value("height"),
x2=alt.value("width"),
y2=alt.value(0),
)
(points + diagonal).interactive()
Линия равенства x=y
При сравнении связанных переменных, например прогнозируемых и фактических значений, линия идеального соответствия x=y упрощает сравнение. В отличие от диагонали в пикселях, эта линия должна находиться в пространстве данных, поэтому используется alt.datum, а не alt.value.
Для статической диаграммы координаты можно задать вручную. Чтобы линия сохранялась при масштабировании и перемещении, её нужно вычислять динамически выражением domain, которое обновляет координаты при каждом изменении диапазона x или y:
import altair as alt
import pandas as pd
import numpy as np
rng = np.random.RandomState(42)
actual = rng.uniform(10, 90, 50)
predicted = actual + rng.normal(0, 12, 50)
source = pd.DataFrame({"actual": actual, "predicted": predicted})
points = alt.Chart(source).mark_circle(size=60).encode(
x=alt.X("actual:Q"),
y=alt.Y("predicted:Q"),
)
identity_line = alt.Chart().mark_rule(strokeDash=[4, 4]).encode(
x=alt.datum(alt.expr("domain('x')[0]"), type="quantitative"),
y=alt.datum(alt.expr("domain('x')[0]"), type="quantitative"),
x2=alt.datum(alt.expr("domain('x')[1]")), # inherits "quantitative" from x
y2=alt.datum(alt.expr("domain('x')[1]")), # inherits "quantitative" from y
) # either the x or y domain could be used to compute the line coordinates
(points + identity_line).interactive()