Altair: ordering of legend labels

Created on 30 Jul 2018  路  12Comments  路  Source: altair-viz/altair

Hi Jake,

Can we change around the order of the legend entries?

Say, put Google at the top in this example from the docs:

import altair as alt
from vega_datasets import data

stocks = data.stocks()

alt.Chart(stocks).mark_line().encode(
    x='date',
    y='price',
    color='symbol'
)

visualization 12

question

Most helpful comment

You can specify the order using the sort property of the channel. Categories will appear in the specified order, and any remaining categories will be appended in arbitrary order. So if all you care is that GOOG is first, you can do this:

import altair as alt
from vega_datasets import data

stocks = data.stocks()

alt.Chart(stocks).mark_line().encode(
    x='date',
    y='price',
    color=alt.Color('symbol', sort=['GOOG'])
)

visualization 29

All 12 comments

You can specify the order using the sort property of the channel. Categories will appear in the specified order, and any remaining categories will be appended in arbitrary order. So if all you care is that GOOG is first, you can do this:

import altair as alt
from vega_datasets import data

stocks = data.stocks()

alt.Chart(stocks).mark_line().encode(
    x='date',
    y='price',
    color=alt.Color('symbol', sort=['GOOG'])
)

visualization 29

Oh this is great. I should have guessed that. Thanks very much.

Hi Jake,

I'm trying to follow your instructions here for reording the legend labels. For some reason the "stock prices" example works, but when using my own data I get an error despite the same data structure and Altair code. What am I missing here? Note that the json works fine in the Vega editor for both examples.

this works

import altair as alt
from vega_datasets import data

stocks = data.stocks()

alt.Chart(stocks).mark_line().encode(
    x='date',
    y='price',
    color=alt.Color('symbol', sort=['GOOG', 'IBM'])
)

this doesn't

df

(I'm hiding some of the data here but you can see the structure)

alt.Chart(data_melt).mark_line().encode(
    x='year',
    y='percentage of students',
    color=alt.Color('percent categories', sort=['applied to university only', 'applied to college only'])
)

Javascript Error: Expression parse error: "datum.percent categories === 'applied to university only' ? 0 : datum.percent categories === 'applied to college only' ? 1 : 2". This usually means there's a typo in your chart specification. See the JavaScript console for the full traceback.

I can't reproduce this error. If I run the following it works without an issue:

import altair as alt
import pandas as pd

data = pd.DataFrame({'year': range(2010, 2016),
                     'percentage of students': range(10, 16),
                     'percent categories': 3 * ['applied to university only', 'applied to college only']})

alt.Chart(data).mark_line().encode(
    x='year',
    y='percentage of students',
    color=alt.Color('percent categories', sort=['applied to university only', 'applied to college only'])
)

How odd. If I run the code you just sent I get the same error.

You may need to update your frontend to get a newer version of vega/vega-lite.

This error is not coming from Python, it is coming from Javascript, so it is the javascript library version that is relevant here. That library version is not controlled by Altair, but controlled by the extension your frontend (jupyterlab, jupyter notebook, colab, etc.) is using to render Altair's outputs.

Okay thanks. I will upgrade JL and try again.

I updated JL and your example works but only if no layering present. If I layer some dots, the legend goes back to its original ordering.


import altair as alt
import pandas as pd

data = pd.DataFrame({'year': range(2010, 2016),
                     'percentage of students': range(10, 16),
                     'percent categories': 3 * ['applied to university only', 'applied to college only']})


base=alt.Chart(data).encode(    
    x='year:O',
    y='percentage of students',
    color=alt.Color('percent categories', sort=['applied to university only', 'applied to college only'])
)

line=base.mark_line()
dot=base.mark_circle()
both=line+dot
both

visualization 13

Ah I see. Thanks for letting me know.

This should be fixed as of Altair 4.0

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zanarmstrong picture zanarmstrong  路  4Comments

nielsmde picture nielsmde  路  4Comments

maxgerma picture maxgerma  路  3Comments

Juan-132 picture Juan-132  路  3Comments

dzonimn picture dzonimn  路  3Comments