【发布时间】:2021-02-11 11:26:00
【问题描述】:
这里的用例是分析聚类的结果;我们想选择一个集群和一个特征(所以两个下拉菜单),并显示一个分层直方图,显示“集群”中点的“特征”分布,分层“集群”外点的“特征”分布。” 额外的限制是我们需要独立的 HTML,所以我们不能使用任何需要 python 内核的东西。
在探索了plotly 和bokeh 之后,Altair 给了我最接近的解决方案(如下)。
输入数据是这样的:
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
Here is an image of the resulting viz, not the interactive form.
有没有办法实现这一点,但两个直方图是分层的?
【问题讨论】:
-
用
alt.layer替换alt.vconcat不正确吗?我试过了,一切似乎都正常。 -
@jakevdp 哇,我觉得很害羞。我认为在
alt.layer失败后,我做了一些重构,将add_selection放在组合图表上而不是每个图表上,这一定消除了我看到的错误。非常感谢您花时间查看以及您构建的软件包。 -
有道理!很高兴它现在可以工作了
标签: python visualization altair