简体   繁体   English

如何对我的图中每行的Y轴标签进行排序?

[英]How to sort Y-axis labels different for each row in my plot?

I want each subplot to sort the labels based on the value defining the size of the bar. 我希望每个子图根据定义条形大小的值对标签进行排序。

See example image: 见示例图片:

在此输入图像描述

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)

In the example, the labels (A, B) are now sorted based on the mean of all values for those labels. 在示例中,标签(A,B)现在根据这些标签的所有值的平均值进行排序。 I want the order to be BA for label X and AB for label Y (so descending based on the value of the label showed in the row of the Altair plot). 我希望订单为标签X的BA和标签Y的AB(因此,根据Altair图的行中显示的标签值降序)。

I tried using facet but that did not resolve the issue. 我尝试使用facet但是没有解决问题。 I provide the code here because it can maybe inspire a solution : 我在这里提供代码,因为它可以激发解决方案:

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

排序分组条形图

Still the row order is ['B', 'A'] for variable x and y. 对于变量x和y,行顺序仍为['B','A']。 I was hoping to have ['A', 'B] for the variable y bar chart. 我希望变量y条形图有['A','B]。

Further elaborating on the solution provided by jakevdp, i obtain this: 进一步详细阐述了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

带选择器的分组条形图和每个图表的排序

By design facet charts share their axes, so it means that when you sort the column you are sorting both axes by the entire dataset. 通过设计构面图共享它们的轴,这意味着当您对列进行排序时,您将按整个数据集对两个轴进行排序。

If you would like each chart to have its axis sorted individually, I believe the only way to do that is to manually filter the dataset and concatenate the charts. 如果您希望每个图表单独对其轴进行排序,我认为唯一的方法是手动过滤数据集并连接图表。 Here is one way you might do this: 这是你可以这样做的一种方式:

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 has shared scales by default, but you can override scale resolution with the resolve property: 默认情况下,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"}}
)

在此输入图像描述

Note that you can no longer use the row encoding shorthand in Altair 2 since unit specifications with row/column in Altair 2 (and Vega-Lite 2) do not have the resolve property. 请注意,您不能再在Altair 2中使用行编码速记,因为Altair 2(和Vega-Lite 2)中具有行/列的单元规范没有resolve属性。 We now added resolve to Vega-Lite 3, thus I think you should be able to do the following once Altair 3 is out: 我们现在为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.

相关问题 Matplotlib 图在 y 轴上显示 2 个标签 - Matplotlib plot shows 2 labels on the y-axis 绘制许多具有不同比例尺的y轴:如何紧缩图形 - Plot with many y-axis in different scales: how to tight figure 如何在 Python 中制作具有两个不同 Y 轴的 Plot - How to Make a Plot with Two Different Y-axis in Python 如何在使用 librosa.display.specshow 创建的 plot 中删除 Y 轴标签、刻度和轴 label - How to remove the Y-axis labels, ticks and axis label in a plot created using librosa.display.specshow 如何在 y 轴上绘制高斯分布? - How to plot a Gaussian Distribution on y-axis? Plot 具有不同的 x 轴和 y 轴使用 matplotlib - Plot with different x-axis and y-axis using matplotlib 如何用pyplot在相同的x轴(日期时间)但不同的y轴上绘制线形图和条形图? - How to plot line and bar-chart on the same x-axis (datetime) but different y-axis with pyplot? 如何更改 plotly 中的 x 轴和 y 轴标签? - How to change the x-axis and y-axis labels in plotly? 如何使用 matplotlib 在一个图中截断子图 y 轴上非常长的刻度标签并整齐地适合 plot 和标签? - How to truncate very long tick labels on y-axis of subplots and fit plot and labels neatly in one fig using matplotlib? Matplotlib:绘制偏移曲线,每个曲线都有相应的y轴 - Matplotlib: plot offset curves, each with corresponding y-axis
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM