如何将单个文本标签添加到 Altair 散点图中的最大点?
How do you add a single text label to the max point in an Altair scatter plot?
我正在尝试在 Altair 中创建一个散点图,我想向具有最大 y 的点添加文本标签或注释。
我已经能够将 text_marks 添加到所有点,但我不知道如何根据 max(y)
标记特定点
下面是一些示例数据:
df = pd.DataFrame(columns=['date', 'daily', 'total'],
data=[['2019-08-01', 29, 102370],
['2019-08-02', 18, 102388],
['2019-08-03', 19, 102407],
['2019-08-04', 13, 102420],
['2019-08-05', 29, 102449],
['2019-08-06', 49, 102498],
['2019-08-07', 31, 102529],
['2019-08-08', 39, 102568],
['2019-08-09', 23, 102591],
['2019-08-10', 17, 102608],
['2019-08-11', 18, 102626],
['2019-08-12', 38, 102664],
['2019-08-13', 22, 102686]])
这是我到目前为止想出的,但它没有达到我想要的效果,我想我可能把它复杂化了
chart = alt.Chart(
data=df,
).mark_line(
color='red'
).encode(
alt.X('date:T', title=''),
alt.Y('daily:Q', title='')
)
text = alt.Chart(df).mark_text().encode(
x=alt.X('max(date):T'),
y=alt.Y('max(daily):Q'),
text=alt.Text('max(daily):Q')
)
(chart + text)
有两种方法可以做你想做的事:
- 用
pandas
过滤数据(对我来说这是最简单的但并不总是简单或可用,
- vega-lite 版本,带有过滤器:
transform_window
对数据进行排序,transform_filter
仅保留最大值
Pandas版本:
chart = (
alt.Chart(data=df)
.mark_line(color="red")
.encode(alt.X("date:T", title=""), alt.Y("daily:Q", title=""))
)
text = (
alt.Chart(df.query("daily == daily.max()"))
.mark_text(dy=-15, color="red")
.encode(x=alt.X("date:T"), y=alt.Y("daily:Q"), text=alt.Text("daily:Q"))
)
(chart + text)
Vega-lite 版本:
chart = (
alt.Chart(data=df)
.mark_line(color="red")
.encode(alt.X("date:T", title=""), alt.Y("daily:Q", title=""))
)
text = (
alt.Chart(df)
.mark_text(dy=-15, color="red")
.transform_window(
sort=[alt.SortField("daily", order="descending")],
rank="rank(daily)"
)
.transform_filter(alt.datum.rank == 1)
.encode(x=alt.X("date:T"),
y=alt.Y("daily:Q"),
text=alt.Text("daily:Q"))
)
(chart + text)
这两个代码都产生了下面的图表:
在 Vega-Lite 语法中执行此操作的一种简洁方法是使用 argmax
聚合。例如:
chart = alt.Chart(
data=df,
).mark_line(
color='red'
).encode(
alt.X('date:T', title=''),
alt.Y('daily:Q', title='')
)
text = alt.Chart(df).mark_text(dy=-15, color="red").encode(
x=alt.X('date:T', aggregate={'argmax': 'daily'}),
y=alt.Y('max(daily):Q'),
text=alt.Text('max(daily):Q')
)
chart + text
我正在尝试在 Altair 中创建一个散点图,我想向具有最大 y 的点添加文本标签或注释。
我已经能够将 text_marks 添加到所有点,但我不知道如何根据 max(y)
标记特定点下面是一些示例数据:
df = pd.DataFrame(columns=['date', 'daily', 'total'],
data=[['2019-08-01', 29, 102370],
['2019-08-02', 18, 102388],
['2019-08-03', 19, 102407],
['2019-08-04', 13, 102420],
['2019-08-05', 29, 102449],
['2019-08-06', 49, 102498],
['2019-08-07', 31, 102529],
['2019-08-08', 39, 102568],
['2019-08-09', 23, 102591],
['2019-08-10', 17, 102608],
['2019-08-11', 18, 102626],
['2019-08-12', 38, 102664],
['2019-08-13', 22, 102686]])
这是我到目前为止想出的,但它没有达到我想要的效果,我想我可能把它复杂化了
chart = alt.Chart(
data=df,
).mark_line(
color='red'
).encode(
alt.X('date:T', title=''),
alt.Y('daily:Q', title='')
)
text = alt.Chart(df).mark_text().encode(
x=alt.X('max(date):T'),
y=alt.Y('max(daily):Q'),
text=alt.Text('max(daily):Q')
)
(chart + text)
有两种方法可以做你想做的事:
- 用
pandas
过滤数据(对我来说这是最简单的但并不总是简单或可用, - vega-lite 版本,带有过滤器:
transform_window
对数据进行排序,transform_filter
仅保留最大值
Pandas版本:
chart = (
alt.Chart(data=df)
.mark_line(color="red")
.encode(alt.X("date:T", title=""), alt.Y("daily:Q", title=""))
)
text = (
alt.Chart(df.query("daily == daily.max()"))
.mark_text(dy=-15, color="red")
.encode(x=alt.X("date:T"), y=alt.Y("daily:Q"), text=alt.Text("daily:Q"))
)
(chart + text)
Vega-lite 版本:
chart = (
alt.Chart(data=df)
.mark_line(color="red")
.encode(alt.X("date:T", title=""), alt.Y("daily:Q", title=""))
)
text = (
alt.Chart(df)
.mark_text(dy=-15, color="red")
.transform_window(
sort=[alt.SortField("daily", order="descending")],
rank="rank(daily)"
)
.transform_filter(alt.datum.rank == 1)
.encode(x=alt.X("date:T"),
y=alt.Y("daily:Q"),
text=alt.Text("daily:Q"))
)
(chart + text)
这两个代码都产生了下面的图表:
在 Vega-Lite 语法中执行此操作的一种简洁方法是使用 argmax
聚合。例如:
chart = alt.Chart(
data=df,
).mark_line(
color='red'
).encode(
alt.X('date:T', title=''),
alt.Y('daily:Q', title='')
)
text = alt.Chart(df).mark_text(dy=-15, color="red").encode(
x=alt.X('date:T', aggregate={'argmax': 'daily'}),
y=alt.Y('max(daily):Q'),
text=alt.Text('max(daily):Q')
)
chart + text