Интерактивный выбор сюжета не освещает точки

Я пытаюсь создать 2 участка в Альтаире, которые имеют одинаковые selection,

Я хотел бы построить точечные и гистограммы населения (y) и возраста (x). Я использую встроенный набор данных Altair population, Население является суммой people столбец в этом наборе данных. Набор данных имеет столбцы для year, people, age а также sex, Я могу получить полное заполнение, используя sum(people) и построить это как y против age, Для гистограммы я могу построить аналогично sum(people) по сравнению с возрастом и цветом, используя sex колонка.

Я пытаюсь настроить кисть / выделение между этими 2 графиками, чтобы можно было подсветить график рассеяния, и одновременно график гистограммы обновляется в соответствии с этим выделением. Тем не менее, я застрял со следующей проблемой

Я использую пример многослойной гистограммы из документации Altair для примера.

Вот код

import altair as alt
from altair.expr import datum, if_
from vega_datasets import data
interval = alt.selection_interval(encodings=['x', 'y'])

df = data.population.url

scatter = alt.Chart(df).mark_point().encode(
    alt.X('age:O', axis=alt.Axis(title='')),
    y='sum(people)',
    color=alt.condition(interval, 'sex:N', alt.value('lightgrey'))
).transform_filter(
    filter = datum.year == 2000
).transform_calculate(
    "sex", if_(datum.sex == 2, 'Female', 'Male')
).properties(
    selection=interval
)

bar = alt.Chart(df).mark_bar(opacity=0.7).encode(
    alt.X('age:O', scale=alt.Scale(rangeStep=17)),
    alt.Y('sum(people)', stack=None),
    color=alt.condition(interval, 'sex:N', alt.value('lightgrey')),
).transform_filter(
    filter = datum.year == 2000
).transform_calculate(
    "sex", if_(datum.sex == 2, 'Female', 'Male')
).properties(height=100, width=400)

scatter & bar

Я изменил код в примере документации. Сначала я создаю график рассеяния, а затем использую цвет на основе selection, Затем я определяю гистограмму тех же двух столбцов и снова использую selection указать цвет. Вот вывод

Теперь я хотел бы перетащить рамку по верхнему (рассеянному) графику, чтобы выбрать несколько точек, и одновременно нижняя (столбчатая) диаграмма должна обновиться на основе selection, Когда я перетаскиваю верхний график, чтобы сделать мой selection, Бывает

Проблемы

  1. После перетаскивания для выбора на верхнем графике цвета (внутри и снаружи выделения) на обоих графиках изменяются на lightgrey, Я ожидал, что на обоих графиках внутри выделения / кисти будет выделено, но снаружи должно быть lightgrey,

Как я могу получить выделение, подсвеченное одновременно на верхнем и нижнем графиках?

РЕДАКТИРОВАТЬ

Мне нужно такое поведение, когда кисть / выделение на одном графике одновременно подсвечивается на втором (связанном) графике.

Версии пакета:

Python = 3.6
Altair = 2.2
Jupyter = 5.6

2 ответа

Решение

Чтобы инициировать выборку для агрегированного значения, лучше всего использовать агрегированное преобразование, чтобы определить это количество так, чтобы оно было доступно для всей диаграммы.

Вот пример:

import altair as alt
from altair.expr import datum, if_
from vega_datasets import data

interval = alt.selection_interval(encodings=['x', 'y'])


base = alt.Chart(data.population.url).transform_filter(
    filter = datum.year == 2000
).transform_calculate(
    "sex", if_(datum.sex == 2, 'Female', 'Male')
).transform_aggregate(
    population="sum(people)",
    groupby=['age', 'sex']
)

scatter = base.mark_point().encode(
    alt.X('age:O', title=''),
    y='population:Q',
    color=alt.condition(interval, 'sex:N', alt.value('lightgrey'))
).properties(
    selection=interval
)

bar = base.mark_bar(opacity=0.7).encode(
    alt.X('age:O', scale=alt.Scale(rangeStep=17)),
    alt.Y('population:Q'),
    color=alt.condition(interval, 'sex:N', alt.value('lightgrey')),
).properties(height=100, width=400)

scatter & bar

Обратите внимание, что я убрал фильтрацию с помощью выбора интервала на нижнем графике, потому что это не то поведение, которое вы описали.

Основываясь на (и адаптируя) ответе @jakevdp выше, я попробовал нечто похожее на этот пример в разделе "Интерактивные диаграммы" галереи документов.

Вместо использования base объект, я использовал vconcat функция, которая присоединяется к Chart экземпляры и передает преобразование и данные в vconcat объект. Вот подход

import altair as alt
from altair.expr import datum, if_
from vega_datasets import data
interval = alt.selection_interval(encodings=['x', 'y'])

scatter = alt.Chart().mark_point().encode(
    alt.X('age:O', title=''),
    y='population:Q',
    color=alt.condition(interval, 'sex:N', alt.value('lightgrey'))
).properties(
    selection=interval
)

bar = alt.Chart().mark_bar(opacity=0.7).encode(
    alt.X('age:O', scale=alt.Scale(rangeStep=17)),
    alt.Y('population:Q'),
    color=alt.condition(interval, 'sex:N', alt.value('lightgrey')),
).properties(height=100, width=400)

alt.vconcat(scatter, bar,
    data=data.population.url
).transform_filter(
    filter = datum.year == 2000
).transform_calculate(
    "sex", if_(datum.sex == 2, 'Female', 'Male')
).transform_aggregate(
    population="sum(people)",
    groupby=['age', 'sex']
)

Этот подход, по-видимому, дает те же функциональные возможности, что и @jakevdp's answer.ie. Можно сделать выбор на диаграмме рассеяния (вверху), и при необходимости это будет отражено в гистограмме (внизу).

Другие вопросы по тегам