Добавить легенду на линии и бары на диаграмму Альтаира, не используя размер / цвет - PullRequest
1 голос
/ 01 мая 2020

Я использую Altair для создания диаграммы с несколькими линиями, каждая из которых имеет несколько полос (представляющих разные CI), и я пытаюсь понять, как я могу добавить легенду. Например, в этом значительно более простом примере:

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')

Как добавить легенду для линии и полос? Я понимаю, что нормальный способ сделать это - по размеру и цвету, но источник данных и данные, которые я использую, заставляют меня делать это, если это возможно?

(Обратите внимание - полосы, по общему признанию, выглядят v. глупо, это полностью фальшивые данные)

1 Ответ

1 голос
/ 01 мая 2020

Единственный способ добавить легенду к диаграмме в Altair / Vega-Lite - добавить кодировку, которая будет представлена ​​легендой. Так что прямой ответ на ваш вопрос «Как добавить легенду без использования размера / цвета» заключается в том, что вы не можете.

В настоящее время лучший способ сделать это - использовать преобразование; что-то вроде этого:

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
)

enter image description here

В будущем, когда Altair будет поддерживать определение datum Vega-Lite, этот подход будет быть немного менее многословным.

...