Add legend to line & bars to Altair chart without using size/color

自作多情 提交于 2021-02-10 14:51:44

问题


I'm using Altair to create a chart with multiple lines each of which has multiple bands (representing different CI) & I'm struggling to understand how I can add a legend. For example, in this considerably simpler example:

import altair as alt
import pandas as pd

df = pd.DataFrame(data={'col1': [1, 2,4,5,6], 'col2': [3, 4,7,4,4], 'col3': [1.5, 2.6,4.6,5.6,6.6], 'col4': [3.6, 4.6,7.6,4.6,4.4],'col5': [1.9, 2.9,4.9,5.9,6.9], 'col4': [3.9, 4.9,7.9,4.9,4.9]})


line = alt.Chart(df).mark_line(color='purple').encode(
    x=alt.X('col1', title='Day'),
    y=alt.Y('col2', title='Column 2')
)

band_90 = alt.Chart(df).mark_area(opacity=0.3, color='purple').encode(
    x=alt.X('col1', title='Day'),
    y='col3',
    y2='col4',
)

band_50 = alt.Chart(df).mark_area(opacity=0.2, color='purple').encode(
    x=alt.X('col1', title='Day'),
    y='col4',
    y2='col5',
)

alt.layer(
    line+band_90+band_50
).save('chart.html')

How can I add a legend for the line & the bands? I understand that the normal way to do it is via size & color but the data source & data I'm using makes me wanna do it this way if possible?

(Please note - the bands admittedly look v. silly, it's completely fake data)


回答1:


The only way to add a legend to a chart in Altair/Vega-Lite is to add an encoding that will be represented by the legend. So the direct answer to your question, "How can I add a legend without using size/color" is that you can't.

The current best way to do this is to use a transform; something like this:

import altair as alt
import pandas as pd

df = pd.DataFrame(data={'col1': [1, 2,4,5,6], 'col2': [3, 4,7,4,4], 'col3': [1.5, 2.6,4.6,5.6,6.6], 'col4': [3.6, 4.6,7.6,4.6,4.4],'col5': [1.9, 2.9,4.9,5.9,6.9], 'col4': [3.9, 4.9,7.9,4.9,4.9]})


base = alt.Chart(df).transform_calculate(
    line="'line'",
    shade1="'shade1'",
    shade2="'shade2'",
)
scale = alt.Scale(domain=["line", "shade1", "shade2"], range=['red', 'lightblue', 'darkblue'])

line = base.mark_line(color='purple').encode(
    x=alt.X('col1', title='Day'),
    y=alt.Y('col2', title='Column 2'),
    color=alt.Color('line:N', scale=scale, title=''),
)

band_90 = base.mark_area(opacity=0.3, color='purple').encode(
    x=alt.X('col1', title='Day'),
    y='col3',
    y2='col4',
    color=alt.Color('shade1:N', scale=scale, title='')
)

band_50 = base.mark_area(opacity=0.2, color='purple').encode(
    x=alt.X('col1', title='Day'),
    y='col4',
    y2='col5',
    color=alt.Color('shade2:N', scale=scale, title='')
)

alt.layer(
    line+band_90+band_50
)

In the future, when Altair supports Vega-Lite's datum definition, this approach will be a bit less verbose.



来源:https://stackoverflow.com/questions/61543503/add-legend-to-line-bars-to-altair-chart-without-using-size-color

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!