Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sort a normalized stacked bar chart with Altair

I am attempting to sort a normalized stacked bar chart based on a specific order.

I would like stacked bars sorted by this order:

Order = dict({'Paid work':1,'Education':2,'Sleep':3,'Other unpaid work':4,'Housework & Shopping':5,'Personal care':6, 'Eating and drinking':7,'TV and Radio':8,'Seeing friends':9,'Other leisures':10})

and Country (Y axis) should be also sorted by the length of "Paid work" bars.

But I've got is this order with "TV & Radio" on the left end side of the chart and cant see in which country people spend time on "paid work" most.

My attempt:

enter image description here

Wrong code:

alt.Chart(df).mark_bar(size=15).encode(
    alt.Y('Country:O'),
    alt.X('Time:Q', stack='normalize',sort=alt.EncodingSortField(field='Order',order='descending')),
    
    alt.Color('Category:N',sort=alt.EncodingSortField(field='Order')),
    tooltip=['Country', 'Category', 'Time']
).properties(
    width=600,
    height=600, title = {'text' :'How do people spend their time?',
'subtitle' : 'Average of minutes per day from time-use diaries for people between 15 and 64'})

I'm new to this platform, please take a look at the data and my simple code in this notebook: https://www.kaggle.com/hoangyennhi/exercise-dv

like image 867
Nhi Hoang Avatar asked Oct 20 '25 14:10

Nhi Hoang


1 Answers

If you set the sort parameter in alt.Color() to either 'ascending' or 'descending', it will sort the stacked bars automatically:

import altair as alt
from vega_datasets import data

source = data.barley()

alt.Chart(source).mark_bar().encode(
    x='sum(yield)',
    y='variety',
    color=alt.Color('site', sort='descending'))

enter image description here

However when you specify a custom sort order it will not as it is not yet supported by Vega-Lite. A workaround was described in this comment, which mentions that you can use a special field called color_<name-of-column>_sort_index, to sort according to the color index. In this example it would look like this:

site_order = ['Duluth', 'Crookston', 'Waseca', 'University Farm', 'Grand Rapids', 'Morris']
alt.Chart(source).mark_bar().encode(
    x='sum(yield)',
    y='variety',
    color=alt.Color('site', sort=site_order),
    order=alt.Order('color_site_sort_index:Q'))

enter image description here

like image 115
joelostblom Avatar answered Oct 23 '25 04:10

joelostblom



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!