我有以下代码,最初是从这里收集的。,它使用matplotlib,shapely,cartopy来绘制世界地图。
单击时,我需要确定它是在哪个国家/地区进行的。我可以向pick_event
画布添加回调,但是,它会在每个艺术家上调用。(cartopy.mpl.feature_artist.FeatureArtist,对应于一个国家)。
给定一个艺术家和一个具有 x、y 坐标的鼠标事件,我如何确定包含?
我试过artist.get_clip_box().contains
了,但它不是真正的多边形,而是一个普通的矩形。
s的默认包含测试FeatureArist
是None
,所以我必须添加自己的包含测试。
如何在 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()