Prueba de contención de polígonos en matplotlib artist

Tengo el siguiente código, recopilado inicialmente deaquí., que usa matplotlib, bien proporcionado, cartopy para dibujar un mapa mundial.

Cuando se hace un clic, necesito determinar en qué país se hizo. Puedo agregar unpick_event la devolución de llamada al lienzo, sin embargo, se llama a todos los artistas (cartopy.mpl.feature_artist.FeatureArtist, que corresponde a un país).

Dado un evento de artista y mouse con coordenadas x, y, ¿cómo puedo determinar la contención?

He intentadoartist.get_clip_box().contains, pero en realidad no es un polígono, sino un rectángulo simple.

La prueba de contención predeterminada paraFeatureArists esNone, así que tuve que agregar mi propia prueba de contención.

¿Cómo puedo verificar correctamente la contención del punto de evento del mouse, dentro del FeatureArtist?

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.io.shapereader as shpreader
import itertools, pdb, subprocess, time, traceback
from itertools import *
import numpy as np
from pydoc import help as h

shapename = 'admin_0_countries'
countries_shp = shpreader.natural_earth(resolution='110m',
                                        category='cultural', name=shapename)

earth_colors = np.array([(199, 233, 192),
                                (161, 217, 155),
                                (116, 196, 118),
                                (65, 171, 93),
                                (35, 139, 69),
                                ]) / 255.
earth_colors = itertools.cycle(earth_colors)

ax = plt.axes(projection=ccrs.PlateCarree())


def contains_test ( artist, ev ):
    print "contain test called"
    #this containmeint test is always true, because it is a large rectangle, not a polygon
    #how to define correct containment test
    print "click contained in %s?: %s" % (artist.countryname, artist.get_clip_box().contains(ev.x, ev.y))
    return True, {}

for country in shpreader.Reader(countries_shp).records():
    # print country.attributes['name_long'], earth_colors.next()
    art = ax.add_geometries(country.geometry, ccrs.PlateCarree(),
                      facecolor=earth_colors.next(),
                      label=country.attributes['name_long'])

    art.countryname = country.attributes["name_long"] 
    art.set_picker(True)
    art.set_contains(contains_test)
    def pickit ( ev ):
        print "pickit called"
        print ev.artist.countryname



def onpick ( event ):
    print "pick event fired"

ax.figure.canvas.mpl_connect("pick_event", onpick)


def onclick(event):
    print 'button=%s, x=%s, y=%s, xdata=%s, ydata=%s'%(event.button, event.x, event.y, event.xdata, event.ydata)

ax.figure.canvas.mpl_connect('button_press_event', onclick)
plt.show()

Respuestas a la pregunta(1)

Su respuesta a la pregunta