[英]How to sort Y-axis labels different for each row in my plot?
我希望每个子图根据定义条形大小的值对标签进行排序。
见示例图片:
data = {'label': ['A','A','B','B'], 'variable': ['x', 'y', 'x', 'y'], 'value':[2,4,3,1]}
df = pd.DataFrame.from_dict(data)
selector = alt.selection_single(empty='all', fields=['label'])
bar = alt.Chart(df,title='My Plot').mark_bar().encode(
alt.Y('label', sort=alt.EncodingSortField(field="value", op="mean", order='ascending'), axis=alt.Axis(title='Label')),
alt.X('value:Q', axis=alt.Axis(format='%', title='Value')),
alt.Row('variable', title='Variable'),
color=alt.condition(selector, alt.value('orange'), alt.value('lightgray')),
tooltip=[alt.Tooltip('label', title='Label'),
alt.Tooltip('value:Q', format='.2%', title='Value'),]
).add_selection(selector)
chart = (bar).properties(width=700, height=300)
display(chart)
在示例中,标签(A,B)现在根据这些标签的所有值的平均值进行排序。 我希望订单为标签X的BA和标签Y的AB(因此,根据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']。 我希望变量y条形图有['A','B]。
进一步详细阐述了jakevdp提供的解决方案,我得到了这个:
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'
)
默认情况下,Facet具有共享比例,但您可以使用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')
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.