Altair/Vega-Lite 条形图:从聚合字段中过滤前 K 个条形图

Era*_* P. 2 python vega vega-lite altair

例如,我正在可视化一个具有分类字段的数据集。我想创建一个条形图,显示该字段的不同类别及其基数,按“升序”/“降序”顺序排序。这可以简单地通过以下方式实现altair

\n\n
import pandas as pd\nimport altair as alt\n\ndata = {0:{\'Name\':\'Mary\', \'Sport\':\'Tennis\'},\n    1:{\'Name\':\'Cal\', \'Sport\':\'Tennis\'},\n    2:{\'Name\':\'John\', \'Sport\':\'Tennis\'},\n    3:{\'Name\':\'Jane\', \'Sport\':\'Tennis\'},\n    4:{\'Name\':\'Bob\', \'Sport\':\'Golf\'},\n    5:{\'Name\':\'Jerry\', \'Sport\':\'Golf\'},\n    6:{\'Name\':\'Gustavo\', \'Sport\':\'Golf\'},\n    7:{\'Name\':\'Walter\', \'Sport\':\'Swimming\'},\n    8:{\'Name\':\'Jessy\', \'Sport\':\'Swimming\'},\n    9:{\'Name\':\'Patric\', \'Sport\':\'Running\'},\n    10:{\'Name\':\'John\', \'Sport\':\'Shooting\'}}\n\ndf = pd.DataFrame(data).T\n\nbars = alt.Chart(df).mark_bar().encode(\n    x=alt.X(\'count():Q\', axis=alt.Axis(format=\'.0d\', tickCount=4)),\n    y=alt.Y(\'Sport:N\', \n        sort=alt.SortField(op=\'count\', field=\'Sport:N\', order=\'descending\'))\n)\nbars\n
Run Code Online (Sandbox Code Playgroud)\n\n

条形图(完整)

\n\n

现在假设我只对前三个最多的类别感兴趣。使用“transform_window”和 \xe2\x80\x9ctransform_filter\xe2\x80\x9d 来过滤数据似乎是合理的,但我无法找到一种方法来这样做。我还尝试了Vega-Lite Top K 示例,尝试对其进行调整,但没有成功(我的“最佳”尝试如下所示)。

\n\n
bars.transform_window(window=[alt.WindowFieldDef(op=\'count\', \n                                                 field=\'Sport:N\',\n                                                 **{\'as\':\'cardinality\'})],\n                      frame=[None, None])\n\nbars.transform_window(window=[alt.WindowFieldDef(op=\'rank\',\n                                                 field=\'cardinality\',\n                                                 **{\'as\':\'rank\'})],\n                      frame=[None, None],\n                      sort=[alt.WindowSortField(field=\'rank\',\n                                                order=\'descending\')])\n\nbars.transform_filter( ..... what??? .....)\n
Run Code Online (Sandbox Code Playgroud)\n

jak*_*vdp 5

我可能会首先使用聚合转换来计算每个组中的人数,然后按照您链接到的 top-K 示例进行操作。

alt.Chart(df).mark_bar().encode(
    x='count:Q',
    y=alt.Y('Sport:N',
        sort=alt.SortField(field='count', order='descending', op='sum')
    ),
).transform_aggregate(
    count='count()',
    groupby=['Sport']
).transform_window(
    window=[{'op': 'rank', 'as': 'rank'}],
    sort=[{'field': 'count', 'order': 'descending'}]
).transform_filter('datum.rank <= 3')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

请注意,由于底层 Vega-Lite 架构发生了变化,Altair 2.2 版(在我撰写本文时尚未发布)alt.SortField将重命名为。alt.EncodingSortField

(旁注:用于排序和窗口转换的 Altair API 目前相当笨重,但我们正在努力思考如何改进)