Randall Goodwin
Randall Goodwin

Reputation: 1976

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.

Upvotes: 4

Views: 2472

Answers (1)

jakevdp
jakevdp

Reputation: 86330

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.

Upvotes: 4

Related Questions