python - Altair:在 LayerChart 中应用选择和 ~selection
问题描述
这里的用例是分析聚类的结果;我们想选择一个集群和一个特征(所以两个下拉菜单),并显示一个分层直方图,显示“集群”中点的“特征”分布,分层“集群”外点的“特征”分布。” 额外的限制是我们需要独立的 HTML,所以我们不能使用任何需要 python 内核的东西。
在探索plotly
and之后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
有没有办法实现这一点,但是两个直方图是分层的?
解决方案
根据评论,解决方案是替换alt.vconcat
为alt.layer
.
推荐阅读
- liferay - 如何在 Liferay 7.1 的 jsp 中嵌入导航 portlet?
- python - 使用未知数量的参数从 python 调用 vba 宏
- javascript - 如何将变量从 .js 页面传递到 .aspx 页面并在 .aspx.js 页面中提供给我?
- mongodb - 如何编写高效的mongodb查询?
- css - 修改样式属性的 CSS 代码
- java - 在java中替换字符串的正则表达式
- tensorflow - 无法在 PyCharm 2019.2 中导入 Keras(来自 TensorFlow 2.0)
- angular - 用于传递数据父级的 Observable 和 EventEmitter (Angular)
- python - 将 Python 配置为复杂的 Django 项目
- amazon-web-services - 由 ansible 提供的打包程序在 aws codebuild 中失败