Altair 等值线地图,基于折线图选择的颜色突出显示

2024-01-09

我正在绘制由字段着色的分区统计图Passenger_0_以及显示演变的折线图Passenger_0_一整天由zone.

我想选择一行(zone)在线图中,并在地图中突出显示它,反之亦然(在地图中选择一个区域,并在折线图中突出显示它)。

目前,我可以在选择线条时更改地图的整体颜色,但不知道如何仅更改所选区域的颜色。

我将不胜感激任何帮助。

为了重现该示例,您需要下载这两个文件:

输出数据.csv https://drive.google.com/file/d/1EtjHDHVf9FpJSP5cZY5t8A9SoPQGnoSF

出租车区.geojson https://drive.google.com/file/d/1cVMsL1amqJNJrHXm2VMJudn2LV-vuw0f/view?usp=sharing

然后运行这段代码得到一个名为的GeoDataFramelong_df:

import altair as alt
import pandas as pd
import geopandas as gpd
import json

geo_json_file_loc= './taxi_zones.geojson'

with open(geo_json_file_loc) as json_data:
    data = json.load(json_data)
    
gdf = gpd.GeoDataFrame.from_features((data))
gdf = gdf[gdf['borough']=='Manhattan']
gdf = gdf[['location_id','zone','geometry']]
gdf = gdf.rename(columns={'location_id':'LocationID'})
gdf['LocationID'] = pd.to_numeric(gdf['LocationID'])

output_data = pd.read_csv('./output_data.csv',sep=',')

def load_taxis_data(output_data, shape_data):
    df_to_visualize = shape_data.copy()
    pickups = output_data.groupby(['hour','dayofweek','LocationID']).sum()
    listofdays = pd.unique(output_data['dayofweek'])

    for hour in range(24):
        for dayofweek in listofdays:
            # get pickups for this hour and weekday
            p = pd.DataFrame(pickups.loc[(hour, dayofweek)]).reset_index()
        
            # add pickups to the Taxi Zones DataFrame       
            df_to_visualize = pd.merge(df_to_visualize, p, on="LocationID", how="left").fillna(0)
            # rename column as per day and hour
            df_to_visualize.rename(columns={"pickups" : "Passenger_%d_%d"%(dayofweek, hour)}, inplace=True)
    return df_to_visualize        

gdf_merged = load_taxis_data(output_data, gdf)

# drop unwanted days
for hour in range(24):
    for dayofweek in [5,6]:
        column_to_drop = "Passenger_%d_%d"%(dayofweek, hour)
        gdf_merged.drop([column_to_drop], axis=1, inplace=True)

gdf_merged.reset_index(level=0, inplace=True)

long_df = pd.wide_to_long(gdf_merged, ["Passenger_0_"], i='index', j="hour")
long_df = long_df.reset_index()

一旦你得到了long_df这是绘图的代码:

dict_json = json.loads(long_df[long_df['hour']==0].to_json())

colours_obj = alt.Color('properties.Passenger_0_:Q',
              scale=alt.Scale(scheme='yelloworangered'),
             title = "Pickups")

sel_line_hover = alt.selection_single(on='mouseover', empty='none')
sel_line_col = alt.selection_single()
sel_line_size = alt.selection_single(empty='none')

base = alt.Chart(alt.Data(values=dict_json['features'])).mark_geoshape(
    stroke='black',
    strokeWidth=1
    ).encode(
    color=alt.condition(sel_line_col, colours_obj, alt.value('lightgray')),
    tooltip = ['properties.zone:O',
               'properties.Passenger_0_:Q']
    ).properties(
    width=350,
    height=750,
    ).add_selection(
    sel_line_col
    )

line = alt.Chart(long_df).mark_line().encode(
    x='hour',
    y='Passenger_0_',
    color=alt.condition(sel_line_hover|sel_line_col, 'zone', alt.value('lightgray')),
    size=alt.condition(sel_line_hover|sel_line_size, alt.value(4),alt.value(1)),
    tooltip = ['zone:O']
    ).properties(
    width=250,
    height=750,
    ).add_selection(
    sel_line_hover,sel_line_col,sel_line_size
    )

base | line

And this is what the plot does: enter image description here

预先感谢您的帮助!


以下是如何在 Altair 中实现双向交互的一般示例,仅使用示例存储库中的数据。关键是设置应该通过选择过滤的功能,甚至通过fields创建选择时的参数。然后,将此选择和相应的条件添加到两个图的相同编码中。

import altair as alt
from vega_datasets import data


state_pop = data.population_engineers_hurricanes()[['state', 'id', 'population']]
state_map = alt.topo_feature(data.us_10m.url, 'states')

click = alt.selection_multi(fields=['state'])

choropleth = (alt.Chart(state_map).mark_geoshape().transform_lookup(
    lookup='id',
    from_=alt.LookupData(state_pop, 'id', ['population', 'state']))
.encode(
    color='population:Q',
    opacity=alt.condition(click, alt.value(1), alt.value(0.2)),
    tooltip=['state:N', 'population:Q'])
.add_selection(click)
.project(type='albersUsa'))

bars = (
    alt.Chart(
        state_pop.nlargest(15, 'population'),
        title='Top 15 states by population').mark_bar().encode(
    x='population',
    opacity=alt.condition(click, alt.value(1), alt.value(0.2)),
    color='population',
    y=alt.Y('state', sort='x'))
.add_selection(click))

choropleth & bars
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Altair 等值线地图,基于折线图选择的颜色突出显示 的相关文章

随机推荐