簡體   English   中英

Matplotlib pick_event 不適用於 geopandas dataframe

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM