Reputation: 1976
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:
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
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()
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