首页 > 解决方案 > Altair:在 LayerChart 中应用选择和 ~selection

问题描述

这里的用例是分析聚类的结果;我们想选择一个集群和一个特征(所以两个下拉菜单),并显示一个分层直方图,显示“集群”中点的“特征”分布,分层“集群”外点的“特征”分布。” 额外的限制是我们需要独立的 HTML,所以我们不能使用任何需要 python 内核的东西。

在探索plotlyand之后bokehAltair给了我最接近的解决方案(如下)。

输入数据是这样的:

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

df = pd.DataFrame({"cluster": np.random.choice([1, 2], size=100)})  # cluster labels
df["feature1"] = np.random.normal(loc=1, scale=0.7, size=100) + df["cluster"]  # a feature column
df["feature2"] = np.random.normal(loc=10, scale=1, size=100) - 3*df["cluster"]  # a second feature column
   cluster  feature1  feature2
0        2       3.4       4.5
1        2       2.4       3.9
2        1       1.6       5.7
3        1       1.6       5.7
4        2       3.3       4.5

我首先融化到:

dfm = pd.melt(df.set_index('cluster', drop=True), ignore_index=False, var_name='feature')
dfm.reset_index(inplace=True)  # Get cluster labels as a column again
   cluster   feature  value
0        2  feature1    3.4
1        2  feature1    2.4
2        1  feature1    1.6
3        1  feature1    1.6
4        2  feature1    3.3

我有代码工作,除了我必须使用VConcatChart而不是LayerChart因为集群选择我需要应用于selection一个直方图(集群中的点)和~selection另一个(集群外的点)。

input_dropdown = alt.binding_select(options=[1,2], name='cluster  ')
selection = alt.selection_single(fields=['cluster'], bind=input_dropdown, name='filter_cluster', init={'cluster': 1})
input_dropdown2 = alt.binding_select(options=['feature1', 'feature2'], name='feature  ')
selection2 = alt.selection_single(fields=['feature'], bind=input_dropdown2, name='filter_feature', init={'feature': 'feature1'})

x_domain = alt.selection_interval(bind='scales', encodings=['x'])

hist1 = alt.Chart(dfm).transform_filter(
    selection & selection2
).transform_joinaggregate(  # to achieve normed histogram
    total='count(*)'
).transform_calculate(  # to achieve normed histogram
    pct='1 / datum.total'
).mark_bar(
    opacity=0.3, interpolate='step', color='green'
).encode(
    alt.X('value:Q', bin=alt.BinParams(maxbins=50), title="feature value", axis=None),
    alt.Y('sum(pct):Q', title="frequency"),
)

hist2 = alt.Chart(dfm).transform_filter(
    ~selection & selection2
).transform_joinaggregate(  # to achieve normed histogram
    total='count(*)'
).transform_calculate(  # to achieve normed histogram
    pct='1 / datum.total'
).mark_bar(
    opacity=0.3, interpolate='step', color='black'
).encode(
    alt.X('value:Q', bin=alt.BinParams(maxbins=50), title="feature value"),
    alt.Y('sum(pct):Q', title="frequency")
)

conc = alt.vconcat(
    hist1,
    hist2
).add_selection(
    selection
).add_selection(
    selection2
).configure_concat(
    spacing=0
).add_selection(
    x_domain
).resolve_scale(
    x='shared'
)

conc

这是生成的可视化的图像,而不是交互式表单。

有没有办法实现这一点,但是两个直方图是分层的?

标签: pythonvisualizationaltair

解决方案


根据评论,解决方案是替换alt.vconcatalt.layer.


推荐阅读