Altair: Legend for layered series inconsistency and unexpected behaviour

Created on 15 Mar 2019  路  3Comments  路  Source: altair-viz/altair

Hi, I am not sure how the legend should work for layered series. If color is used I get the following behaviour:

# data
x = np.linspace(0, 12 * np.pi, 100)
scales = [0.33, 0.66, 1, 1.33, 1.66]
dfs = [
    pd.DataFrame({'x': x,
                  'sin(x)': np.sin(x / 5) * scale,
                  'cos(x)': np.cos(x / 5) * scale + 0.20,
                  'sin_scale': [scale] * len(x),
                  'cos_scale': [scale + 0.20] * len(x)
                 }) for scale in scales]

data = pd.concat(dfs, ignore_index=True, sort=False)

```python

charts

sin = alt.Chart(data).mark_line(strokeWidth=3).encode(
x='x',
y='sin(x)',
color=alt.Color('sin_scale:O',
scale=alt.Scale(scheme='blues'),
legend=alt.Legend(title='sin scale', format='.3f'))
)
cos = alt.Chart(data).mark_line(strokeWidth=3).encode(
x='x',
y='cos(x)',
color=alt.Color('cos_scale:O',
scale=alt.Scale(scheme='reds'),
legend=alt.Legend(title='cos scale', format='.3f'))
)

While `sin` and `cos` will have proper legends and colours, the resulting layered `sin+cos` will result in a single colour with an aggregated legend. However these are two different series, shouldn't the colours and the legend be preserved for each of them?

![image](https://user-images.githubusercontent.com/1670348/54427871-63c8a780-4724-11e9-9565-07379d57d1ce.png)


Using `opacity` at least preserves the colours (unfortunately not the legends):

```python
sin = alt.Chart(data).mark_line(strokeWidth=3, color="blue").encode(
    x='x',
    y='sin(x)',
    opacity=alt.Opacity('sin_scale:O',
                    #scale=alt.Scale(scheme='blues'),
                    legend=alt.Legend(title='sin scale', format='.3f'))
)
cos = alt.Chart(data).mark_line(strokeWidth=3, color='red').encode(
    x='x',
    y='cos(x)',
    opacity=alt.Opacity('cos_scale:O',
                    #scale=alt.Scale(scheme='reds'),
                    legend=alt.Legend(title='cos scale', format='.3f'))
)

image

Ideally shouldn't the resulting legend list the different scale values under each legend title with its respective colour?

documentation

Most helpful comment

When you combine multiple charts by layering or concatenation, their scales will be shared by default. If you'd like the scales to be independent, you can specify that with resolve_scale.

From your top plot:

(sin + cos).resolve_scale(color='independent')

visualization (6)

All 3 comments

When you combine multiple charts by layering or concatenation, their scales will be shared by default. If you'd like the scales to be independent, you can specify that with resolve_scale.

From your top plot:

(sin + cos).resolve_scale(color='independent')

visualization (6)

I apologise for replying late to this.

Yes, that's exactly what I needed. I'll look how it is discussed in the documentation and if I can improve it because it seems to me it's an important use-case - see for example lineplot in seaborn which lets you have different series with different colours.

Your solution solves my issue so feel free to close it if you consider the default behaviour is unproblematic (I do not have enough experience with the library to judge this :) ).

The default behavior is determined by Vega-Lite, so it's not really a discussion to be had here.

I do think shared scales are one place where the documentation is currently pretty lacking, so any contribution there would be very welcome.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

LukeMathWalker picture LukeMathWalker  路  3Comments

mroswell picture mroswell  路  4Comments

maxgerma picture maxgerma  路  3Comments

morberg picture morberg  路  3Comments

nielsmde picture nielsmde  路  4Comments