[英]Matplotlib “pick_event” not working in embedded graph with FigureCanvasTkAgg
[英]Matplotlib pick_event not working with geopandas dataframe
这是我的Jupyer Notebook 源代码。
但是下面是一个硬编码的可重现示例。 (您需要从我的 Github 或真实来源访问 UK.geojson 文件: http://geoportal1-ons.opendata.arcgis.com/datasets/687f346f5023410ba86615655ff33ca9_1.geojson )
我有一个 geopandas DataFrame 到 plot 英国 map 然后 plot 在它上面的某些坐标(公园运行位置)。
我希望能够交互式地“选择”坐标,然后我将对其进行编码以显示有关该特定运行位置的信息。
我不明白为什么我调用的fig.canvas.mpl_connect('pick_event', onpick)
function 不起作用。
有人可以帮我解决这个问题吗?
import pandas as pd
import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt
##### Create hardcoded dataset ######
df = pd.DataFrame.from_dict({0: {'parkrun_name': 'Beeston',
'location_name': 'Weirfields Recreation Ground',
'longitude': -1.201737,
'latitude': 52.913592,
'Run Date': '12/11/2022',
'Run Number': 370.0,
'Pos': 107.0,
'Time': '26:05',
'Age Grade': '49.46%',
'PB?': np.nan},
1: {'parkrun_name': 'Colwick',
'location_name': 'Colwick Country Park, Nottingham',
'longitude': -1.09786,
'latitude': 52.945171,
'Run Date': '22/10/2022',
'Run Number': 511.0,
'Pos': 127.0,
'Time': '29:44',
'Age Grade': '43.39%',
'PB?': np.nan},
2: {'parkrun_name': 'Exmouth',
'location_name': 'Exmouth',
'longitude': -3.412392,
'latitude': 50.614697,
'Run Date': '24/12/2022',
'Run Number': 189.0,
'Pos': 197.0,
'Time': '25:44',
'Age Grade': '50.13%',
'PB?': 'PB'},
}, orient='index')
###### Read in the UK Map File ######
uk = gpd.read_file("uk.geojson")
###### Convert df to geodf ######
gdf = gpd.GeoDataFrame(
df, geometry=gpd.points_from_xy(df.longitude, df.latitude)
)
gdf.crs = "EPSG:4326"
gdf = gdf.to_crs(uk.crs)
###### Plot interactive map ######
%matplotlib widget
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111)
uk.plot(ax=ax, alpha=0.8)
def onclick(event):
ax = plt.gca()
# ax.set_title(f"You selected {event.x}, {event.y}")
line = event.artist
xdata, ydata = line.get_data()
ind = event.ind
tx = f"{np.array([xdata[ind], ydata[ind]]).T}"
ax.set_title(f"{tx}")
gdf[gdf['Run Date'].isna()].plot(ax=ax, color='black', marker='.', markersize=8, alpha=0.2, picker=20)
gdf[gdf['Run Date'].notna()].plot(ax=ax, color='#AAFF00', marker='.', markersize=50, picker=20)
ax.set_xlim(-7,2)
ax.set_ylim(49,60)
cid = fig.canvas.mpl_connect('pick_event', onclick)
我是EOmaps的开发者,一个 package 旨在简化 matplotlib/cartopy 地图的交互。
它还具有使地理数据框可选取的功能......这可能正是您正在寻找的:-)
这是一个关于它目前如何工作的例子:
(查看有关 地理数据框和回调的文档以获取更多信息)
from eomaps import Maps
m = Maps()
m.add_feature.preset.coastline()
# fetch a geodataframe from NaturalEarth (with polygon geometries)
countries = m.add_feature.cultural.admin_0_countries.get_gdf(scale=110)
# fetch a geodataframe from NaturalEarth (with point geometries)
populated_places = m.add_feature.cultural.populated_places.get_gdf(scale=110)
# add the geo-dataframes to the map and make them "pickable"
m.add_gdf(countries, column="NAME", alpha=0.5,
picker_name="countries", pick_method="contains")
m.add_gdf(populated_places, column="NAME",
picker_name="populated_places", pick_method="centroids")
# attach a pre-defined callback to show an annotation if you pick a geometry
m.cb.pick__countries.attach.annotate(
text=lambda val, **kwargs: f"clicked in country:\n {val}"
)
m.cb.pick__populated_places.attach.annotate(
text=lambda val, **kwargs: f"closest city to click-position:\n {val}",
xytext=(20,-20)
)
# define a custom callback
def custom_cb(ID, val, pos, picker_name, **kwargs):
print(f"### {picker_name} picked ID '{ID}' with value: '{val}' at position '{pos}'")
# execute the custom callback if you pick a geometry
m.cb.pick__populated_places.attach(custom_cb)
m.cb.pick__countries.attach(custom_cb)
m.ax.set_extent((-180.0, 180.0, -90.0, 90.0))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.