use*_*757 5 python vega-lite altair
我在 Altair 中生成折线图。我想控制哪些行位于行堆栈的“顶部”。在我的示例中,我希望红线位于顶部(最新日期),然后下降到黄色(最旧日期)位于底部。
我试图用sortof 的参数来控制它alt.Color ,但无论sort='ascending'或sort='descending'线重叠的顺序都不会改变。
我怎样才能控制这个?希望我可以在不对源数据帧本身进行排序的情况下完成此操作。
data = [{'review_date': dt.date(year=2022, month=2, day=24), 'a':19, 'b':17, 'c':12, 'd':8},
{'review_date': dt.date(year=2022, month=2, day=23), 'a':20, 'b':16, 'c':14, 'd':8},
{'review_date': dt.date(year=2022, month=2, day=22), 'a':22, 'b':16, 'c':14, 'd':10},
{'review_date': dt.date(year=2022, month=2, day=21), 'a':14, 'b':13, 'c':12, 'd':5},]
df = pd.DataFrame(data).melt(id_vars=['review_date'], value_name='price', var_name='contract')
df.review_date = pd.to_datetime(df.review_date)
domain = df.review_date.unique()
range_ = ['red', 'blue', 'gray', 'yellow']
alt.Chart(df, title='foo').mark_line().encode(
x=alt.X('contract:N'),
y=alt.Y('price:Q',scale=alt.Scale(zero=False)),
color=alt.Color('review_date:O', sort="ascending", scale=alt.Scale(domain=domain, range=range_) )
).interactive()
Run Code Online (Sandbox Code Playgroud)
默认情况下,图形标记按照它们在数据框中出现的顺序绘制(正如您所指出的),这意味着数据框中最后的元素将最后绘制并最终位于图表的顶部(称为最高“层”或最高的“z 顺序”):
import pandas as pd
import altair as alt
df = pd.DataFrame({
'a': [1, 2, 1, 2],
'b': [1.1, 2.1, 1.0, 2.2],
'c': ['point1', 'point1', 'point2', 'point2']
})
alt.Chart(df).mark_circle(size=1000).encode(
x='a',
y='b',
color='c'
)
Run Code Online (Sandbox Code Playgroud)
设置sort颜色编码的参数时,您不会更改点的 z 顺序,而只是更改为它们分配颜色的顺序。在下图中,“point2”仍然位于顶部,但它现在是蓝色而不是橙色:
alt.Chart(df).mark_circle(size=1000).encode(
x='a',
y='b',
color=alt.Color('c', sort='descending')
)
Run Code Online (Sandbox Code Playgroud)
如果我们想更改 z 顺序以使“point1”位于顶部,我们必须使用编码来指定order:
alt.Chart(df).mark_circle(size=1000).encode(
x='a',
y='b',
color='c',
order=alt.Order('c', sort='descending')
)
Run Code Online (Sandbox Code Playgroud)
但是,正如您在 Vega-Lite 文档中所读到的,编码order对于堆叠标记和路径标记(包括线标记)具有特殊行为,它控制点在一条线上连接的顺序,而不是它们的 z 排序/分层。
因此,我相信实现所需行为的唯一方法是对该列进行排序。您可以在图表构建期间执行此操作:
alt.Chart(df).mark_line(size=10).encode(
x='a',
y='b',
color='c'
)
Run Code Online (Sandbox Code Playgroud)
alt.Chart(df.sort_values('c', ascending=False)).mark_line(size=10).encode(
x='a',
y='b',
color='c'
)
Run Code Online (Sandbox Code Playgroud)