我正在绘制一个由字段Passenger_0_
着色的choropleth映射和一个折线图,以Passenger_0_
的形式显示zone
在一天中的演变。
我想在折线图中选择一条线(zone
,并将其突出显示在地图中,反之亦然(在地图中选择一个区域,并将其突出显示在折线图中)。
目前,我可以在选择线条时更改地图的整个颜色,但是不知道如何仅更改所选区域的颜色。
我将不胜感激。
为了复制示例,您需要下载以下两个文件:
然后运行这段代码以获取名为long_df
的GeoDataFrame:
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
预先感谢您的帮助!
答案 0 :(得分:3)
以下是如何在 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