Altair 中的世界地图 + 滑块 (Python)

问题描述 投票:0回答:2

我想使用 Python 中的 Altair 库构建一个带有世界地图的交互式图表,其中包含每个国家/地区的 COVID-19 确诊病例和日期滑块。

数据格式:

"country_region","date","confirmed_cases"
"Afghanistan",2020-01-22,0
"Afghanistan",2020-01-23,0
"Afghanistan",2020-01-24,0
"Afghanistan",2020-01-25,0

我已成功构建非交互式图表,但无法设置滑块。我的图表现在看起来像这样:enter image description here

我想添加滑块来选择日期,但无法正确设置。

我使用

transform_lookup
方法根据数据(确诊病例/人口)为国家添加颜色,据我了解,当用户更改滑块位置时,应添加
transform_filter
来执行数据过滤。但这行不通。我的假设是,在
transform_lookup
中始终使用原始数据,并且过滤在那里不起作用。我还没有找到有关同时使用
transform_lookup
和滑块的示例或文档。

如果有任何可以帮助我解决这个问题的想法,我将不胜感激。

代码:

import requests
import json

import pandas as pd

import altair as alt
from vega_datasets import data
from altair import datum

df = pd.read_csv('https://raw.githubusercontent.com/MariaKokshaikina/any-data/main/covid19_global_confirmed_cases%20(1).csv')

country_info = requests.get(
    'https://raw.githubusercontent.com/MariaKokshaikina/any-data/main/country_info.json'
).json()

df = df[df['country_region'].isin(country_info)]
df = df.sort_values('date', ascending=True)
df = df.tail(5000)

def timestamp(t):
    return pd.to_datetime(t).timestamp() * 1000

df['id'] = df['country_region'].map(lambda x: country_info[x]['numericCode'])
df['rate'] = df['confirmed_cases'] / df['country_region'].map(lambda x: country_info[x]['population'])
df['timestamp'] = df['date'].map(timestamp)

countries = alt.topo_feature(data.world_110m.url, 'countries')

slider = alt.binding_range(
    step=24 * 60 * 60 * 1000,
    min=df['timestamp'].min(), 
    max=df['timestamp'].max()
)

select_date = alt.selection_single(
    name="slider", 
    fields=['timestamp'],
    bind=slider, 
)

alt.Chart(countries).mark_geoshape()\
    .encode(color='rate:Q')\
    .add_selection(select_date)\
    .transform_filter(select_date)\
    .transform_lookup(
        lookup='id',
        from_=alt.LookupData(df, key='id', fields=['rate'])
    )\
    .project('equirectangular')\
    .properties(
        width=500,
        height=300,
        title='Title'
    )

  • 您可以删除
    .transform_filter(select_date)\
    线以使用滑块查看工作地图,这不会改变任何内容。
python plot charts jupyter-notebook altair
2个回答
4
投票

问题似乎是在 Vega 中,查找变换不会根据选择动态重新计算。您可以通过切换主数据源来解决此问题,以便所有时间戳都出现在最终连接的数据集中:

alt.Chart(df).mark_geoshape()\
    .encode(color='rate:Q')\
    .add_selection(select_date)\
    .transform_filter(select_date)\
    .transform_lookup(
        lookup='id',
        from_=alt.LookupData(countries, key='id',
                             fields=["type", "properties", "geometry"])
    )\
    .project('equirectangular')\
    .properties(
        width=500,
        height=300,
        title='Title'
    )

enter image description here


0
投票

我意识到这是一个较旧的问题,但对于任何仍在努力解决在自己的代码中应用杰克建议的问题的人(就像我所做的那样),我找到了替代解决方案!

我最终完全放弃了“transform_lookup”并直接在 GeoPandas 中处理它:

import geopandas as gpd
    
url = data.world_110m.url #in my case, this was a github url
gdf = gpd.read_file(url)
    
merged_data = pd.merge(gdf, df, on='id', how='left')

然后地图的代码将更接近“正常”图表,只需加载一个数据:

alt.Chart(merged_data).mark_geoshape()\
    .encode(color='rate:Q')\
    .add_selection(select_date)\
    .transform_filter(select_date)\
    .project('equirectangular')\
    .properties(
        width=500,
        height=300,
        title='Title'
    )

我希望这可以帮助那些在transform_lookup工作中遇到困难的人:)

© www.soinside.com 2019 - 2024. All rights reserved.