Как добавить слайдер на хороплет в альтаире?

Я пытаюсь добавить ползунок к своему графику.
Ползунок основан на «годах» с 2006 по 2012 г.
Мои данные выглядят так:
data
Его можно скачать отсюда:
sample_data.csv
Когда я рисую диаграмму на уровне округа, она выполняет внутреннее соединение с код fips для округа с помощью transform_lookup
Это мой код:

slider = alt.binding_range(min=2006, max=2012, step=1)
select_year = alt.selection_single(name="year", fields=['year'],
                                   bind=slider, init={'year': 2006})

alt.Chart(us_counties).mark_geoshape(
    stroke='black',
    strokeWidth=0.05
).project(
    type='albersUsa'
).transform_lookup(
    lookup='id',
    from_=alt.LookupData(fdf, 'fips', ['Pill_per_pop','year'])
).transform_calculate(
    Pill_per_pop='isValid(datum.Pill_per_pop) ? datum.Pill_per_pop : -1'  
).encode(
    color = alt.condition(
        'datum.Pill_per_pop > 0',
        alt.Color('Pill_per_pop:Q', scale=Scale(scheme='blues')),
        alt.value('#dbe9f6')
    )).add_selection(
    select_year
).properties(
    width=700,
    height=400
).transform_filter(
    select_year
)


Этот код дает мне график хороплет с ползунком, но графики неправильные.
Я чувствую, что это происходит впервые для кода fips и не фильтруется по году.
Мне кажется, это из-за метода transform_lookup, сопоставляющего идентификаторы округов с кодом FIP.
Это результат:
 введите описание изображения здесь

введите здесь описание изображения  введите описание изображения здесь  введите описание изображения здесь


person sdasara    schedule 07.12.2019    source источник


Ответы (1)


Вы правы, что преобразование поиска находит только первый соответствующий индекс - это одностороннее соединение, а не многосоединение. Если вы хотите объединить несколько записей данных для одного ключа, вам придется использовать набор данных с несколькими столбцами.

Для своих данных вы можете создать такой набор данных, используя pandas pivot, а затем в Altair вы можете отменить эту операцию после поиска, используя свернуть преобразование

Для ваших данных это может выглядеть примерно так:

import altair as alt
import pandas as pd
from vega_datasets import data

us_counties = alt.topo_feature(data.us_10m.url, 'counties')
fdf = pd.read_csv('https://raw.githubusercontent.com/sdasara95/Opioid-Crisis/master/sample_data.csv')
fdf['year'] = fdf['year'].astype(str)
fdf = fdf.pivot(index='fips', columns='year', values='Pill_per_pop').reset_index()
columns = [str(year) for year in range(2006, 2013)]

slider = alt.binding_range(min=2006, max=2012, step=1)
select_year = alt.selection_single(name="year", fields=['year'],
                                   bind=slider, init={'year': 2006})

alt.Chart(us_counties).mark_geoshape(
    stroke='black',
    strokeWidth=0.05
).project(
    type='albersUsa'
).transform_lookup(
    lookup='id',
    from_=alt.LookupData(fdf, 'fips', columns)
).transform_fold(
    columns, as_=['year', 'Pill_per_pop']
).transform_calculate(
    year='parseInt(datum.year)',
    Pill_per_pop='isValid(datum.Pill_per_pop) ? datum.Pill_per_pop : -1'  
).encode(
    color = alt.condition(
        'datum.Pill_per_pop > 0',
        alt.Color('Pill_per_pop:Q', scale=alt.Scale(scheme='blues')),
        alt.value('#dbe9f6')
    )).add_selection(
    select_year
).properties(
    width=700,
    height=400
).transform_filter(
    select_year
)

введите здесь описание изображения

person jakevdp    schedule 07.12.2019
comment
Я использую ваш подход, но не могу. Я предоставил данные по запросу. - person sdasara; 08.12.2019
comment
Обновил ответ данными - проблема заключалась в том, что я предполагал, что столбец года был строками. - person jakevdp; 08.12.2019