7

为折线图指定工具提示时,工具提示仅在沿线悬停在点上时出现,但在沿线悬停在其他任何位置时不会出现。这在使用非线性插值时尤其成问题......有没有办法在线条本身上明确设置工具提示?

import altair as alt
from vega_datasets import data

source = data.jobs.url

alt.Chart(source).mark_line(interpolate="basis").encode(
    alt.X('year:O'),
    alt.Y('perc:Q', axis=alt.Axis(format='%')),
    color='sex:N',
    tooltip='sex:N'
).properties(
    title='Percent of work-force working as Welders'
).transform_filter(
    alt.datum.job == 'Welder'
)

在此处输入图像描述

4

3 回答 3

6

从@Philipp_Kats 的回答和@dominik 的评论(以及其他偶然发现此线程并希望查看 Altair 代码示例的人)扩展而来,目前实现“工具提示”效果的方法是:

  1. 创建行 ( mark_line())
  2. 创建一个选择最近点并根据 x 值进行选择的选择
  3. 沿线捕捉一些透明选择器,通知线不同位置的 x 值
  4. 层 ( mark_text()) 在上面 1 - 3 上面

一个真实的例子是我制作的一个简单 Flask 应用程序上的折线图。唯一的区别是我没有使选择器透明(opacity=alt.value(0)),否则它是一个带有工具提示的折线图。

这是使用 OP 的原始数据集的可重现示例:

# Step 1: create the line
line = alt.Chart().mark_line(interpolate="basis").encode(
    x=alt.X("year:O"),
    y=alt.Y("perc:Q", axis=alt.Axis(format='%')),
    color='sex:N'
).transform_filter(
    alt.datum.job == 'Welder'
)

# Step 2: Selection that chooses nearest point based on value on x-axis
nearest = alt.selection(type='single', nearest=True, on='mouseover',
                            fields=['year'])


# Step 3: Transparent selectors across the chart. This is what tells us
# the x-value of the cursor
selectors = alt.Chart().mark_point().encode(
    x="year:O",
    opacity=alt.value(0),
).add_selection(
    nearest
)

# Step 4: Add text, show values in Sex column when it's the nearest point to 
# mouseover, else show blank
text = line.mark_text(align='left', dx=3, dy=-3).encode(
    text=alt.condition(nearest, 'sex:N', alt.value(' '))
)

# Layer them all together
chart = alt.layer(line, selectors, text, data=source, width=300)

chart

结果图:

在此处输入图像描述

于 2019-04-16T06:22:28.893 回答
3

我怀疑目前是否有直接的技术解决方案:-(

一种解决方法是在线条顶部显式添加点,以便更容易悬停。我通常使它们相对较大,但在悬停事件之前隐藏,例如这里作为顶部的樱桃,可以使用 Voronoi 显示任何给定点的最近点,就像他们在本教程中所做的那样

如果您需要 Altair 代码示例,请告诉我,我使用的是原始 vega,但实现 Altair 版本应该相对简单

于 2018-11-13T22:14:50.597 回答
0

截至 2022 年 3 月,一种解决方法是在不使用选择器和 Voronoi 镶嵌使您的规范过于复杂的情况下:在背景中使用粗透明线(opacity不应该完全是0,因为它不会被渲染)并创建一个layer chart.

base = (
    alt.Chart(
        pd.DataFrame(
            [{"x": 1, "y": 1}, {"x": 2, "y": 2}, {"x": 3, "y": 1}, {"x": 4, "y": 4}]
        )
    )
    .mark_line()
    .encode(x="x:Q", y="y:Q", tooltip="tt:N")
    .transform_calculate(tt="datum.x+' value'")
)
tt = base.mark_line(strokeWidth=30, opacity=0.01)
base + tt
于 2022-03-01T23:11:45.197 回答