Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort facets of an Altair plot bases on group statistic

I would like to change the order of the facets of an Altair chart based based on some groups statistics such as mean, sigma, etc.

In some cases, the ordering function may be more complex, such as the delta between two moving averages, slope of an EWMA, etc, so I would also like to be able to "pass" in the order if possible.

Here's the testable case code:

import pandas as pd
import numpy as np
import altair as alt

alt.renderers.enable('notebook')

# make some data to test
N = 500
df = pd.DataFrame({
    'Date Time': pd.date_range('2019-06-19', periods=N, freq='H'),
    'A':  np.random.normal(6, 1, N),
    'B': np.random.normal(5, 1, N),
    'C': np.random.normal(7, 1, N),
    'D': np.random.normal(8, 1, N)
}).melt('Date Time')

# render the chart using facets
p = alt.Chart(df).mark_point().encode(
    facet='variable',
    y='value',
    x='Date Time',
    color='variable',
)

# set some aditional properties
p.properties(width=230, height=150, columns=3).resolve_scale()

Which produces this chart where the facets are sorted alphabetically:

enter image description here

I would like the sort order to be largest mean to smallest mean:

var_order = df.groupby('variable').mean().sort_values('variable', ascending=False).index.values
var_order

which produces:

array(['D', 'C', 'B', 'A'], dtype=object)

I read some posts that indicate sorting on x and y is possible, but this is case where I would like to sort the faces themselves.

like image 463
Randall Goodwin Avatar asked Sep 19 '25 08:09

Randall Goodwin


1 Answers

You can use an EncodingSortField on the facet encoding; e.g.

p = alt.Chart(df).mark_point().encode(
    y='value',
    x='Date Time',
    color='variable',
    facet=alt.Facet('variable',
        sort=alt.EncodingSortField('value', op='mean', order='descending')
    )
)

# set some aditional properties
p.properties(width=230, height=150, columns=3).resolve_scale()

chart output

For more complicated calculations, you can use a calculate transform and/or aggregate transform to compute a new field, and sort by that.

like image 50
jakevdp Avatar answered Sep 20 '25 21:09

jakevdp