Altair/Vega-Lite热图如何按相对丰度均值筛选保留Top5分类单元
解决方法
你可以通过Altair自带的转换算子组合实现Top 5分类单元的筛选,不需要提前处理DataFrame,修改后的代码如下:
import pandas as pd import numpy as np import altair as alt from vega_datasets import data from altair_saver import save # 读取文件并将空值填充为0 df = pd.read_excel("path\to\df") doNotMelt = df.drop(df.iloc[:,1:], axis=1) df_melted = pd.melt(df, id_vars = doNotMelt, var_name = 'SampleID', value_name = 'Relative_abundance') # 关闭Altair最大行数限制 alt.data_transformers.disable_max_rows() alt.Chart(df_melted).mark_rect().encode( alt.X('SampleID:N'), alt.Y('Lowest_Taxon:N', sort=alt.EncodingSortField(field='Relative_abundance', op='mean', order='descending')), alt.Color('Relative_abundance:Q') # 新增以下3行转换逻辑 ).transform_joinaggregate( # 按分类单元分组计算平均丰度,赋值给该分类单元对应的所有行 mean_abun='mean(Relative_abundance)', groupby=['Lowest_Taxon'] ).transform_window( # 按平均丰度降序给分类单元生成排名 rank='rank(desc(mean_abun))' ).transform_filter( # 仅保留排名前5的分类单元 alt.datum.rank <=5 )
转换逻辑说明
transform_joinaggregate不会改变原始数据的行数,只会给每个Lowest_Taxon对应的所有行新增一列mean_abun,存储该分类单元的平均相对丰度transform_window基于平均丰度降序生成排名,同一分类单元的所有行排名完全一致- 最后
transform_filter过滤掉排名大于5的行,就能保留你需要的Top5分类单元,原有的Y轴排序逻辑不需要调整,依然会按平均丰度从高到低排列
如果存在平均丰度相同的分类单元需要调整排名规则,把transform_window里的rank替换为dense_rank即可。
内容的提问来源于stack exchange,提问作者Protaeus
相关产品推荐
相关产品推荐

