是否可以根据其中一个类别的值对 Altair 分组条形图的列进行排序?
Is it possible to sort the columns of an Altair grouped bar chart based on the value of one of the categories?
我有以下图表 -
我希望能够对列进行排序(不是单个组的各个条 - 我已经知道该怎么做),即订购 3 sub-chart - 如果你将 - 基于我选择的任何类别(a
、b
或 c
)的值。
我尝试使用 alt.SortField
和 alt.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' 排序,那么右列应该在第一位,然后是左列,最后是中间列。
这有点复杂,但您可以通过一系列转换来做到这一点:
- a Calculate Transform 到 select 您要排序的值
- a Join-Aggregate Transform 和
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',
)
然后按"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',
)
我有以下图表 -
我希望能够对列进行排序(不是单个组的各个条 - 我已经知道该怎么做),即订购 3 sub-chart - 如果你将 - 基于我选择的任何类别(a
、b
或 c
)的值。
我尝试使用 alt.SortField
和 alt.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' 排序,那么右列应该在第一位,然后是左列,最后是中间列。
这有点复杂,但您可以通过一系列转换来做到这一点:
- a Calculate Transform 到 select 您要排序的值
- a Join-Aggregate Transform 和
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',
)
然后按"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',
)