Altair: Sort not working on alt.Y?

Created on 24 Mar 2018  路  9Comments  路  Source: altair-viz/altair

Hi,

Trying to sort a bar chart on another field, not getting the expected results.

My data in DataFrame:

  location  name                 score sort_order   target
0   A   Elwood Dempsey      10  1   20
1   B   Migdalia Mcferron   23  2   25
2   B   Takisha Rodiguez    32  2   25
3   C   Aurea Heinecke          34  3   30
4   A   Sofia Donofrio           5  1   20
5   B   Cecile Eubanks          56  2   25
6   D   Haley Curfman           23  4   40
7   A   Keenan Israel           44  1   20
8   B   Bethanie Nicosia     9  2   25
9   C   Dominga Sterns           4  3   30

My Altair code to display a bar chart:

alt.Chart(data).mark_bar().encode(
        alt.Y('name:N', sort= {"op": "distinct", "field": "sort_order:O"}),
        alt.X('score:Q'),
        color={"field": 'location:N', "sort": {"op": "distinct", "field": "sort_order:O"}}
        )

Result:
bart_chart_sorting

The legend is sorted correctly on sort_order, however Y isn't sorted at all. Y is displayed in the order from the datasource. If I remove the Y sort attribute, Y is sorted alphabetically (as expected).

Question: is this a bug of I'm missing something?

Most helpful comment

Sorting layered charts does not work because of a bug in Vega-Lite. I believe it will be fixed in the Vega-Lite 3.0 release, which will be supported by Altair version 3.0.

All 9 comments

It will work with the following:
alt.Y('name:N', sort=alt.SortField(field="sort_order", op="sum", order='ascending')),

Thank you for pointing me to SortField, that works. Now, I want to make this a LayerChart and add mark_tick() to this. I've re-written the call to facilitate the LayerChart.

Original bar chart

base = alt.Chart(data).encode(
        alt.Y('name:N', sort=alt.SortField(field="sort_order", op="sum", order='ascending')))

bar = base.mark_bar().encode(
        alt.X('score:Q'),
        alt.Color('location:N', sort=alt.SortField(field="sort_order", op="distinct", order='ascending'))
        )
bar

This outputs:
versie_b_in_base_2
Which is perfect!

Now adding the tick.

base = alt.Chart(data).encode(
        alt.Y('name:N', sort=alt.SortField(field="sort_order", op="sum", order='ascending')))

bar = base.mark_bar().encode(
        alt.X('score:Q'),
        alt.Color('location:N', sort=alt.SortField(field="sort_order", op="distinct", order='ascending'))
        )

tick = base.mark_tick().encode(
        alt.X('target:Q')
)
bar+tick

This outputs:
versie_b_met_tick

The legend is still sorted correctly, but the bar graph is now sorted alphabetically again!

What am I mising here?

That looks like a similar issue I ran into and filed bugs here - it ended up being a duplicate of an existing bug reported against vega-lite.

My first issue raised against altair:
https://github.com/altair-viz/altair/issues/549
Then I filed against vega-lite as that is the source:
https://github.com/vega/vega-lite/issues/3566
and that was closed as this looked like a duplicate of this issue that they are currently tracking to resolve:
https://github.com/vega/vega-lite/issues/2177

Thank you, will follow these closely.

Do we know why we cannot sort? And when would this issue be fixed? :)

I am running into the same issue. It would be great to get this resolved.

Sorting layered charts does not work because of a bug in Vega-Lite. I believe it will be fixed in the Vega-Lite 3.0 release, which will be supported by Altair version 3.0.

See the Vega-Lite issues linked above for more information.

Awesome. Looking forward to v3.0

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Juan-132 picture Juan-132  路  3Comments

tonylee3399 picture tonylee3399  路  3Comments

jtbaker picture jtbaker  路  3Comments

SuperShinyEyes picture SuperShinyEyes  路  3Comments

maxgerma picture maxgerma  路  3Comments