基于两列值在 folium 中进行过滤

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

我的目标是利用

ipywidgets
dropdowns
Folium
来过滤和可视化地理数据框。作为示例,让我们考虑一个源自自然地球向量的地理数据框,其中包含“大陆”和“名称”等列。

我的目标是创建一个用户界面,用户可以首先从下拉列表中选择一个大陆。选择后,另一个下拉列表会动态填充该大陆内的国家/地区。最后,当从第二个下拉列表中选择一个国家/地区时,其位置将显示在 Folium 地图上。

我打算将此交互式笔记本另存为 HTML 文件。

下面是我迄今为止尝试过的代码,基于How do add drop down menu for the folium map?

import geopandas as gpd
import ipywidgets
from IPython.display import HTML, display
import folium


df = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))

df = df[['continent', 'geometry']]

out = ipywidgets.Output(layout={'border': '1px solid black'})

w = ipywidgets.Dropdown(
    options=df['continent'].unique().tolist(),
    value=df['continent'].tolist()[0],
    description='Column:',
    disabled=False,
)


# Define a function to filter the dataframe
def filter_dataframe(name):
    return df[df['continent'] == name]


def on_dropdown_change(change):
    out.clear_output()
    df = filter_dataframe(w.value)
    with out: 
        display(df.explore(df.columns[0], cmap="Blues"))

w.observe(on_dropdown_change, names='value')
display(w)

with out:
    display(df.explore(df.columns[0], cmap="Blues"))

out
python folium
1个回答
0
投票

我对 ipywidgets 没有足够的经验。我将在序言中说,可能有更好的代码,但基于 SO 中的answers,我配置了一个包含大陆选择的字典以及与该大陆相关的国家/地区列表。第一个下拉列表中的处理程序具有由大陆选择结果设置的国家/地区列表,第二个下拉列表按大陆值和国家/地区值提取数据帧。

import geopandas as gpd
import ipywidgets
from IPython.display import HTML, display
import folium
import mapclassify

df = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))

continent_group = {}
continent_list = df.continent.unique()[:6]
continent_list.insert(0, 'all')

for c in continent_list:
    dff = df.query('continent == @c')
    continent_group[c] = dff['name'].tolist()

df = df[['continent', 'name', 'geometry']]

out = ipywidgets.Output(layout={'border': '1px solid black'})

w = ipywidgets.Dropdown(
    options=continent_list,
    value=continent_list[0],
    description='Continet:',
    disabled=False,
)

c = ipywidgets.Dropdown(
    description='Counrty:',
    disabled=False,
)

def continent_update(x):
    country_list = continent_group[x]
    c.options = country_list

# Define a function to filter the dataframe
def filter_dataframe(continent_name, country_name):
  #print('country_name:', country_name)
  if country_name is None:
    return df[df['continent'] == continent_name]
  else:
    return df[(df['continent'] == continent_name) & (df['name'] == country_name)]


def dropdown_eventhandler1(change):
    print('w.value',w.value, 'c.value',c.value)
    continent_update(w.value)
    out.clear_output()
    df = filter_dataframe(w.value, None)
    with out: 
      display(df.explore(df.columns[0], cmap="Blues"))

def dropdown_eventhandler2(change):
    #continent_update(w.value)
    out.clear_output()
    df = filter_dataframe(w.value, c.value)
    with out: 
      display(df.explore(df.columns[1], cmap="Blues"))

w.observe(dropdown_eventhandler1, names='value')
c.observe(dropdown_eventhandler2, names='value')

display(w, c)

with out:
    display(df.explore(df.columns[0], cmap="Blues", legend=False))

out

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