能否根据一个类别的值对Altair分组条形图的列进行排序?

4
我有以下图表-
enter image description here
我希望能够对列进行排序(不是单个组的各个条形图 - 我已经知道如何做到这一点),也就是说,基于所选类别(abc)的值来排序3个子图表-如果您愿意。
我尝试使用alt.SortFieldalt.EncodeSortField,它们会移动图表,但如果更改类别以查看它们是否实际工作,则无法正常工作。 代码 -
import altair as alt
import pandas as pd

dummy = pd.DataFrame({'place':['Asia', 'Antarctica','Africa', 'Antarctica', 'Asia', 'Africa', 'Africa','Antarctica', 'Asia'],'category':['a','a','a','b','b','b','c','c','c'],'value':[5,2,3,4,3,5,6,9,5]})
alt.Chart(dummy).mark_bar().encode(
    x=alt.X('category'),
    y='value',
    column=alt.Column('place:N', sort=alt.SortField(field='value', order='descending')),
    color='category',
)

我知道alt.Column('place:N', sort=alt.SortField(field='value', order='descending'))似乎不正确,因为我没有对任何类别进行定位,所以我也尝试了x=alt.X('category', sort=alt.SortField(field='c', order='descending')),但它也不起作用。

期望的输出(假设按降序排列)-

  • 如果我要按'c'排序,则中间列应该首先出现,然后是左边和最后是右边的列。
  • 它似乎已经按'b'排序了。
  • 如果我要按'a'排序,则右边的列应该首先出现,然后是左边和最后是中间的列。
1个回答

3
这有点复杂,但您可以通过一系列的变换来实现:
  • 使用计算变换选择要排序的值
  • 使用连接-聚合变换argmax将所需值连接到每个组
  • 另一个计算变换以从此结果中提取要排序的特定字段
它看起来像这样,首先按"c"排序:
import altair as alt
import pandas as pd

dummy = pd.DataFrame({'place':['Asia', 'Antarctica','Africa', 'Antarctica', 'Asia', 'Africa', 'Africa','Antarctica', 'Asia'],'category':['a','a','a','b','b','b','c','c','c'],'value':[5,2,3,4,3,5,6,9,5]})
alt.Chart(dummy).transform_calculate(
    key="datum.category == 'c'"
).transform_joinaggregate(
    sort_key="argmax(key)", groupby=['place']
).transform_calculate(
    sort_val='datum.sort_key.value'  
).mark_bar().encode(
    x=alt.X('category'),
    y='value',
    column=alt.Column('place:N', sort=alt.SortField("sort_val", order="descending")),
    color='category',
)

enter image description here

"a" 排序:

alt.Chart(dummy).transform_calculate(
    key="datum.category == 'a'"
).transform_joinaggregate(
    sort_key="argmax(key)", groupby=['place']
).transform_calculate(
    sort_val='datum.sort_key.value'  
).mark_bar().encode(
    x=alt.X('category'),
    y='value',
    column=alt.Column('place:N', sort=alt.SortField("sort_val", order="descending")),
    color='category',
)

enter image description here


1
哇...非常感谢,杰克。我必须问一下,你认为我应该读些什么,才能自己想出这些解决方案和创意呢?结果证明,这个解决方案适用于这个虚拟数据,在我的实际数据集中失败了,因为数据略微更加复杂,除了“位置”和“类别”之外,还有一个临时列-“日期”,每个“位置”和“类别”都会多次出现,我需要从“日期”中选择每个类别的最大值,然后进行上述操作。 - jar
1
如果你将 alt.SortField("sort_val") 改为 alt.EncodingSortField("sort_val", op="max"),那么它将按匹配值的最大值进行排序。 - jakevdp
起初它没有起作用,所以我玩了一会儿......除了您建议使用alt.EncodingSortField("sort_val", op="max")之外,我还必须使用placeday两者进行groupby,即sort_key="argmax(key)", groupby=['place', 'day'],然后它就起作用了。非常感谢您的帮助!! - jar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接