分面图的多线工具提示会导致错误

Multi-line tooltip for faceted chart leads to error

我正在尝试在 Altair 中为多面图表设置多线工具提示。该方面有助于比较多年数据(即可以轻松地将 2018 年 1 月与 2019 年 1 月进行比较)。

下面是一个包含随机数据的代码示例,遵循文档中的示例:https://altair-viz.github.io/gallery/multiline_tooltip.html

根据我定义方面的位置,我会收到以下错误之一:

  1. AttributeError: 'FacetChart' object has no attribute 'mark_point' :当我一开始对折线图进行分面然后尝试在此折线图上应用 mark_point() 时发生

  2. ValueError: Faceted charts cannot be layered. : 当我最后对折线图进行分面时(构建图层时)发生

有解决办法吗?

start = pd.Timestamp('20180101', tz='Europe/Rome')
end = pd.Timestamp('20200101', tz='Europe/Rome')
index = pd.date_range(start,end,freq='M')[:-1]

source = pd.DataFrame(np.cumsum(np.random.randn(len(index), 3), 0).round(2),
                    columns=['A', 'B', 'C'], index=index)
source.index.names = ['x']
source = source.reset_index().melt('x', var_name='category', value_name='y')

### line chart with facet
line = alt.Chart(source).mark_line(point=True).encode(alt.X('month(x):O', title=''), alt.Y('y:Q', title=''), color='category:N').facet(row=alt.Row('year(x):O', title=''))


nearest = alt.selection(type='single', nearest=True, on='mouseover',
                        fields=['x'], empty='none')
selectors = alt.Chart(source).mark_point().encode(
    x='x:Q',
    opacity=alt.value(0),
).add_selection(
    nearest
)
points = line.mark_point().encode(
    opacity=alt.condition(nearest, alt.value(1), alt.value(0))
)
text = line.mark_text(align='left', dx=5, dy=-5).encode(
    text=alt.condition(nearest, 'y:Q', alt.value(' '))
)
rules = alt.Chart(source).mark_rule(color='gray').encode(
    x='x:Q',
).transform_filter(
    nearest
)
alt.layer(
    line, selectors, points, rules, text
).properties(
    width=600, height=300
)

如果您想对分层图表进行分面,您应该在该分层图表上调用 .facet() 方法。

您可能还想更改图层中的 x 编码,以便它们都编码相同的内容。

结果如下所示:

import numpy as np
import pandas as pd
import altair as alt

start = pd.Timestamp('20180101', tz='Europe/Rome')
end = pd.Timestamp('20200101', tz='Europe/Rome')
index = pd.date_range(start,end,freq='M')[:-1]

source = pd.DataFrame(np.cumsum(np.random.randn(len(index), 3), 0).round(2),
                    columns=['A', 'B', 'C'], index=index)
source.index.names = ['x']
source = source.reset_index().melt('x', var_name='category', value_name='y')

### line chart with facet
line = alt.Chart(source).mark_line(point=True).encode(alt.X('month(x):O', title=''), alt.Y('y:Q', title=''), color='category:N')


nearest = alt.selection(type='single', nearest=True, on='mouseover',
                        fields=['x'], empty='none')
selectors = alt.Chart(source).mark_point().encode(
    x='month(x):O',
    opacity=alt.value(0),
).add_selection(
    nearest
)
points = line.mark_point().encode(
    opacity=alt.condition(nearest, alt.value(1), alt.value(0))
)
text = line.mark_text(align='left', dx=5, dy=-5).encode(
    text=alt.condition(nearest, 'y:Q', alt.value(' '))
)
rules = alt.Chart(source).mark_rule(color='gray').encode(
    x='month(x):O',
).transform_filter(
    nearest
)
alt.layer(
    line, selectors, points, rules, text
).properties(
    width=600, height=300
).facet(row=alt.Row('year(x):O', title=''))