Python 如何为绘图中的每一行排序不同的Y轴标签?

Python 如何为绘图中的每一行排序不同的Y轴标签?,python,vega-lite,altair,Python,Vega Lite,Altair,我希望每个子批次根据定义条大小的值对标签进行排序 请参见示例图像: 在本例中,现在根据这些标签的所有值的平均值对标签(A、B)进行排序。我希望标签X的顺序为B-A,标签Y的顺序为A-B(因此根据Altair绘图行中显示的标签值降序)。我尝试使用facet,但没有解决问题。我在这里提供代码是因为它可能会激发一个解决方案: import altair as alt import pandas as pd df = pd.DataFrame({'label': ['A','A','B','B'],

我希望每个子批次根据定义条大小的值对标签进行排序

请参见示例图像:


在本例中,现在根据这些标签的所有值的平均值对标签(A、B)进行排序。我希望标签X的顺序为B-A,标签Y的顺序为A-B(因此根据Altair绘图行中显示的标签值降序)。

我尝试使用facet,但没有解决问题。我在这里提供代码是因为它可能会激发一个解决方案:

import altair as alt
import pandas as pd

df = pd.DataFrame({'label': ['A','A','B','B'],
               'variable': ['x', 'y', 'x', 'y'],
               'value':[2,4,3,1]})
bar = alt.Chart(df,title='My Plot').mark_bar().encode(
    alt.Y('label', axis=alt.Axis(title='Label'), 
          sort=alt.EncodingSortField(field="value", op="values", order='descending')),
    alt.X('value:Q', axis=alt.Axis(format='d', title='Value')),
    tooltip=[alt.Tooltip('label', title='Label'),
             alt.Tooltip('value:Q', format='d', title='Value'),]
).facet(
    row='variable:O'
)
bar

对于变量x和y,行顺序仍然是['B','A']。我希望有['A',B]作为可变y条形图

进一步详细说明了VDP提供的解决方案,我得出以下结论:

selector = alt.selection_single(empty='all', fields=['label'])
base = alt.Chart(df, title='My Plot').mark_bar().encode(
    alt.Y('label', axis=alt.Axis(title='Label'), sort=alt.EncodingSortField(field="value", op="sum", order='descending')),
    alt.X('value:Q', axis=alt.Axis(format='d', title='Value')),
    color=alt.condition(selector, alt.value('orange'), alt.value('lightgray')),
    tooltip=[alt.Tooltip('label', title='Label'),
             alt.Tooltip('value:Q', format='d', title='Value'),]
).add_selection(selector)

bar = alt.vconcat(title='My Chart')
for v in df['variable'].unique():
    bar &= base.transform_filter(f"datum.variable == '{v}'").properties(title=f"'{v}'")

bar

按设计镶嵌面图表共享其轴,因此这意味着在对列进行排序时,您将按整个数据集对两个轴进行排序

如果您希望每个图表的轴单独排序,我认为唯一的方法是手动筛选数据集并连接图表。这里有一种方法可以做到这一点:

import altair as alt
import pandas as pd

df = pd.DataFrame({'label': ['A','A','B','B'],
                   'variable': ['x', 'y', 'x', 'y'],
                   'value':[2,4,3,1]})

base = alt.Chart(df).mark_bar().encode(
  alt.Y('label', axis=alt.Axis(title='Label'), 
        sort=alt.EncodingSortField(field="value", op="sum", order='descending')),
  alt.X('value:Q', axis=alt.Axis(format='d', title='Value')),
  tooltip=[alt.Tooltip('label', title='Label'),
           alt.Tooltip('value:Q', format='d', title='Value'),],
)

alt.vconcat(
  base.transform_filter("datum.variable == 'x'").properties(title='x'),
  base.transform_filter("datum.variable == 'y'").properties(title='y'),
  title='My Chart'
)

默认情况下,刻面具有共享比例,但您可以使用resolve属性覆盖比例分辨率:

import altair as alt
import pandas as pd

df = pd.DataFrame({'label': ['A','A','B','B'],
                   'variable': ['x', 'y', 'x', 'y'],
                   'value':[2,4,3,1]})

alt.Chart(df,title='My Plot').mark_bar().encode(
    alt.Y('label', sort=alt.EncodingSortField(field="value", op="mean", order='descending'), axis=alt.Axis(title='Label')),
    alt.X('value:Q', axis=alt.Axis(format='%', title='Value'))
).facet(
    alt.Row('variable', title='Variable'),
    resolve={"scale": {"y": "independent"}}
)

请注意,您不能再在Altair 2中使用行编码速记,因为Altair 2中带有行/列的单元规范(以及Vega Lite 2)没有
resolve
属性。我们现在在Vega Lite 3中添加了
resolve
,因此我认为在Altair 3发布后,您应该能够执行以下操作:


df = pd.DataFrame({'label': ['A','A','B','B'],
                   'variable': ['x', 'y', 'x', 'y'],
                   'value':[2,4,3,1]})

alt.Chart(df,title='My Plot', resolve={"scale": {"y": "independent"}}).mark_bar().encode(
    alt.Y('label', sort=alt.EncodingSortField(field="value", op="mean", order='descending'), axis=alt.Axis(title='Label')),
    alt.X('value:Q', axis=alt.Axis(format='%', title='Value')),
    alt.Row('variable', title='Variable')
)

嗨,杰克,我们实际上可以使用
resolve
使facet使用独立的比例。(见我的答案。):)

df = pd.DataFrame({'label': ['A','A','B','B'],
                   'variable': ['x', 'y', 'x', 'y'],
                   'value':[2,4,3,1]})

alt.Chart(df,title='My Plot', resolve={"scale": {"y": "independent"}}).mark_bar().encode(
    alt.Y('label', sort=alt.EncodingSortField(field="value", op="mean", order='descending'), axis=alt.Axis(title='Label')),
    alt.X('value:Q', axis=alt.Axis(format='%', title='Value')),
    alt.Row('variable', title='Variable')
)