Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Faceted charts with an aggregation don't support a custom sort order of the facets/columns #3386

Closed
4 tasks done
bertiebaggio opened this issue Mar 26, 2024 · 3 comments
Closed
4 tasks done
Labels

Comments

@bertiebaggio
Copy link

bertiebaggio commented Mar 26, 2024

This issue arose as a result of a question I posted on Stack Overflow. @joelostblom directed me here if I could repro using the example datasets, which I can. That said, I am still ready to believe this is a PEBKAC issue if someone tells me I am using altair.Column wrong!

More context, a previous issue here:

#1826

You can specify the order of the columns by passing a list of values to the sort parameter. For example:

However, passing a lit of values to the sort parameter results in a column order that matches the data order:

import altair as alt  
# alt.__version__ == 5.2.0

from vega_datasets import data

source = data.barley()

alt.Chart(source).mark_bar().encode(
    alt.Column('site:N',
               sort=["Waseca", "Morris", "University Farm", 
                     "Grand Rapids", "Crookston", "Duluth"]
              ),
    x='year:O',
    y='sum(yield):Q',
    color='year:N',
)

Results in:

altair-colorder-issue1

data.barley().head()

"""
	yield	variety	year	site
0	27.00000	Manchuria	1931	University Farm
1	48.86667	Manchuria	1931	Waseca
2	27.43334	Manchuria	1931	Morris
3	39.93333	Manchuria	1931	Crookston
4	32.96667	Manchuria	1931	Grand Rapids
"""

I bet this year's barley harvest the next row in that dataframe says "Duluth" !

Is this a Vega Lite Issue?

This does look like potentially a Vega-Lite issue, since the sort order is reproduced in the Vega Lite JS object / JSON but also not honoured in the chart:

//...
  "encoding": {
    "color": {"field": "year", "type": "nominal"},
    "column": {
      "field": "site",
       "sort": [
        "Waseca",
        "Morris",
        "University Farm",
        "Grand Rapids",
        "Crookston",
        "Duluth"
      ]
      "type": "nominal"
    },
    "x": {"field": "year", "type": "ordinal"},
    "y": {"aggregate": "sum", "field": "yield", "type": "quantitative"}
  },
  "$schema": "https://vega.github.io/schema/vega-lite/v5.16.3.json",
// ...

However, I would be grateful if someone more experienced than me could confirm that before I raise the issue there, which I am happy to do :)


Please follow these steps to make it more efficient to solve your issue:

  • Since Altair is a Python wrapper around the Vega-Lite visualization grammar, most bugs should be reported directly to Vega-Lite. You can click the Action Button of your Altair chart and "Open in Vega Editor" to create a reproducible Vega-Lite example and see if you get the same error in the Vega Editor.
  • Search for duplicate issues.
  • Use the latest version of Altair.
  • Describe how to reproduce the bug and include the full code and data to reproduce it, ideally using a sample data set from vega_datasets.
@bertiebaggio
Copy link
Author

bertiebaggio commented Mar 26, 2024

As Joel suggested in the comments on the linked Q, using a different channel ie xOffset orders as spcified when sort is applied to the x axis:

import altair as alt
from vega_datasets import data

source = data.barley()

alt.Chart(source).mark_bar().encode(
    alt.X('site:N', sort=["Waseca", "Morris", "University Farm",
                          "Grand Rapids", "Crookston", "Duluth"]),
    y='sum(yield):Q',
    color='year:N',
    xOffset='year:O',
)

altair-vizbug-xoffset2

@joelostblom
Copy link
Contributor

Thanks for following up here @bertiebaggio ! I can see that things work as expected in the issue you linked. After some exploring, it seems to be an issue with aggregating and sorting facets at the same time. I had no idea this was an existing bug, but it has been reported in VL already here vega/vega-lite#5366; you might be able to ask for workaround there and thumbs up that issue.

If you have the time you can also help to troubleshoot it. Do this by opening the Chart in the VegaEditor and then clicking the "Vega" spec tab at the bottom. Compare the Vega spec for the working non-aggregated faceted chart and with of the non-working aggregated facet to figure out what needs to be change in how Vega-Lite translates the aggregate spec to Vega. This can take some time, but sometimes there are small differences that are easy to spot and reporting them in the issue helps encouraging a fix.

I'll close this issue since there is nothing we can do from the altair side of things to fix it, but a not so elegant workaround could involve sorting the dataframe and then breaking the altair default alphabetical sort:

import altair as alt  
from vega_datasets import data

source = data.barley()
source['site'] = pd.Categorical(source['site'], ["Waseca", "Morris", "University Farm", "Grand Rapids", "Crookston", "Duluth"])
source = source.sort_values('site')

alt.Chart(source).mark_bar().encode(
    x='year:O',
    y='sum(yield):Q',
    color='year:N',
    # Passing `None` to `sort` did not work for me, it kept it as alphabetical.
    # A list seems to work in the sense that it breaks the sort order and falls back on the order in the df
    column=alt.Column('site:N').sort(['sdaf'])
)

image

@joelostblom joelostblom changed the title Trying to apply a custom sort order to columns of a grouped bar chart results in no sort order Faceted charts with an aggregation don't support a custom sort order of the facets/columns Mar 26, 2024
@bertiebaggio
Copy link
Author

Yes, it makes sense to close it here since it does seem to be squarely a VL issue. Thanks for taking the time to dig into this further; good catch on the aggregation, that sailed past me!

Good tip on manually reordering the data as another workaround.

I'll see about troubleshooting / exploring the Vega/VL translation boundary when I get a chance :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants