如何在 python 底图图例中显示 shapefile 标签?
How to show shapefile label in python basemap legend?
python底图绘制了两个内容:多线形状文件(IL_State_ln)和底图范围内一些随机点的散点图。我的兴趣是生成一个图例,该图例提供有关 shapefile 和散点的信息。目前,我只能在图例中包含点,而不能在 shapefile 中包含这些点。
检查 Basemap API documentation 没有提供任何信息,因为函数 readshapefile() 似乎没有任何 label 参数。
您能帮我像在 ArcGIS 地图中那样在图例中包含 shapefile 指示器吗?
这是我的代码:
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.basemap import Basemap
fname = "DATA/GIS/IL_State_ln"
m = Basemap(llcrnrlon=-92.,llcrnrlat=36.8,urcrnrlon=-86.5,urcrnrlat=43.,
resolution='i', projection='tmerc', lat_0 = 36.5, lon_0 = -91.8)
m.readshapefile(fname, 'mygeom')
x,y = m([-90., -91.2, -88.], [38., 37.7, 42.])
m.scatter(x,y, marker='o', label="Points")
plt.legend(loc=3)
plt.show()
我正在使用 Python 3.5、matplotlib 2.0 和底图 1.0.8。
创建图例条目的想法是将形状绘制为多边形,然后可以将其添加到图例中。
因此,我们将首先停用 drawbounds
、m.readshapefile(fn, 'shf', drawbounds = False)
。然后我们可以从 shapefile 创建一个 matplotlib.patches.Polygon
并将其添加到坐标区,plt.gca().add_artist(polygon)
.
然后可以使用此多边形更新图例
handles, labels = plt.gca().get_legend_handles_labels()
handles.extend([polygon])
labels.extend(["Name of the shape"])
plt.legend(handles=handles, labels=labels)
下面是一些正在运行的代码,它会生成以下图像。它使用 ne_10m_admin_0_countries 文件。
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import numpy as np
m = Basemap(llcrnrlon=-10,llcrnrlat=35,urcrnrlon=35,urcrnrlat=60.,
resolution='i', projection='tmerc', lat_0 = 48.9, lon_0 = 15.3)
m.drawcoastlines()
m.drawcountries(zorder=0, color=(.9,.9,.9), linewidth=1)
fn = r"ne_10m_admin_0_countries\ne_10m_admin_0_countries"
m.readshapefile(fn, 'shf', drawbounds = False)
#Madrid
x,y = m([-3.703889],[40.4125])
m.plot(x,y, marker="o", color="blue", label="Madrid", ls="")
# some countries
countries = ['Switzerland', 'Ireland', "Belgium"]
colors= {'Switzerland':"red", 'Ireland':"orange", 'Belgium' : "purple"}
shapes = {}
for info, shape in zip(m.shf_info, m.shf):
if info['NAME'] in countries:
p= Polygon(np.array(shape), True, facecolor= colors[info['NAME']],
edgecolor='none', alpha=0.7, zorder=2)
shapes.update({info['NAME'] : p})
for country in countries:
plt.gca().add_artist(shapes[country])
# create legend, by first getting the already present handles, labels
handles, labels = plt.gca().get_legend_handles_labels()
# and then adding the new ones
handles.extend([shapes[c] for c in countries])
labels.extend(countries)
plt.legend(handles=handles, labels=labels, framealpha=1.)
plt.show()
现在因为我们已经有了一个带有形状的多边形,为什么不通过直接将形状绘制到图例中来让图例更花哨一点。这可以按如下方式完成。
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import numpy as np
m = Basemap(llcrnrlon=-10,llcrnrlat=35,urcrnrlon=35,urcrnrlat=60.,
resolution='i', projection='tmerc', lat_0 = 48.9, lon_0 = 15.3)
m.drawcoastlines()
fn = r"ne_10m_admin_0_countries\ne_10m_admin_0_countries"
m.readshapefile(fn, 'shf', drawbounds = False)
#Madrid
x,y = m([-3.703889],[40.4125])
m.plot(x,y, marker="o", color="blue", label="Madrid", ls="")
countries = ['Switzerland', 'Ireland', "Belgium"]
colors= {'Switzerland':"red", 'Ireland':"orange", 'Belgium' : "purple"}
shapes = {}
for info, shape in zip(m.shf_info, m.shf):
if info['NAME'] in countries:
p= Polygon(np.array(shape), True, facecolor= colors[info['NAME']],
edgecolor='none', alpha=0.7, zorder=2)
shapes.update({info['NAME'] : p})
for country in countries:
plt.gca().add_artist(shapes[country])
class PolygonN(object):
def legend_artist(self, legend, orig_handle, fontsize, handlebox):
x0, y0 = handlebox.xdescent, handlebox.ydescent
width, height = handlebox.width, handlebox.height
aspect= height/float(width)
verts = orig_handle.get_xy()
minx, miny = verts[:,0].min(), verts[:,1].min()
maxx, maxy = verts[:,0].max(), verts[:,1].max()
aspect= (maxy-miny)/float((maxx-minx))
nvx = (verts[:,0]-minx)*float(height)/aspect/(maxx-minx)-x0
nvy = (verts[:,1]-miny)*float(height)/(maxy-miny)-y0
p = Polygon(np.c_[nvx, nvy])
p.update_from(orig_handle)
p.set_transform(handlebox.get_transform())
handlebox.add_artist(p)
return p
handles, labels = plt.gca().get_legend_handles_labels()
handles.extend([shapes[c] for c in countries])
labels.extend(countries)
plt.legend(handles=handles, labels=labels, handleheight=3, handlelength=3, framealpha=1.,
handler_map={Polygon: PolygonN()} )
plt.show()
python底图绘制了两个内容:多线形状文件(IL_State_ln)和底图范围内一些随机点的散点图。我的兴趣是生成一个图例,该图例提供有关 shapefile 和散点的信息。目前,我只能在图例中包含点,而不能在 shapefile 中包含这些点。
检查 Basemap API documentation 没有提供任何信息,因为函数 readshapefile() 似乎没有任何 label 参数。
您能帮我像在 ArcGIS 地图中那样在图例中包含 shapefile 指示器吗?
这是我的代码:
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.basemap import Basemap
fname = "DATA/GIS/IL_State_ln"
m = Basemap(llcrnrlon=-92.,llcrnrlat=36.8,urcrnrlon=-86.5,urcrnrlat=43.,
resolution='i', projection='tmerc', lat_0 = 36.5, lon_0 = -91.8)
m.readshapefile(fname, 'mygeom')
x,y = m([-90., -91.2, -88.], [38., 37.7, 42.])
m.scatter(x,y, marker='o', label="Points")
plt.legend(loc=3)
plt.show()
我正在使用 Python 3.5、matplotlib 2.0 和底图 1.0.8。
创建图例条目的想法是将形状绘制为多边形,然后可以将其添加到图例中。
因此,我们将首先停用 drawbounds
、m.readshapefile(fn, 'shf', drawbounds = False)
。然后我们可以从 shapefile 创建一个 matplotlib.patches.Polygon
并将其添加到坐标区,plt.gca().add_artist(polygon)
.
然后可以使用此多边形更新图例
handles, labels = plt.gca().get_legend_handles_labels()
handles.extend([polygon])
labels.extend(["Name of the shape"])
plt.legend(handles=handles, labels=labels)
下面是一些正在运行的代码,它会生成以下图像。它使用 ne_10m_admin_0_countries 文件。
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import numpy as np
m = Basemap(llcrnrlon=-10,llcrnrlat=35,urcrnrlon=35,urcrnrlat=60.,
resolution='i', projection='tmerc', lat_0 = 48.9, lon_0 = 15.3)
m.drawcoastlines()
m.drawcountries(zorder=0, color=(.9,.9,.9), linewidth=1)
fn = r"ne_10m_admin_0_countries\ne_10m_admin_0_countries"
m.readshapefile(fn, 'shf', drawbounds = False)
#Madrid
x,y = m([-3.703889],[40.4125])
m.plot(x,y, marker="o", color="blue", label="Madrid", ls="")
# some countries
countries = ['Switzerland', 'Ireland', "Belgium"]
colors= {'Switzerland':"red", 'Ireland':"orange", 'Belgium' : "purple"}
shapes = {}
for info, shape in zip(m.shf_info, m.shf):
if info['NAME'] in countries:
p= Polygon(np.array(shape), True, facecolor= colors[info['NAME']],
edgecolor='none', alpha=0.7, zorder=2)
shapes.update({info['NAME'] : p})
for country in countries:
plt.gca().add_artist(shapes[country])
# create legend, by first getting the already present handles, labels
handles, labels = plt.gca().get_legend_handles_labels()
# and then adding the new ones
handles.extend([shapes[c] for c in countries])
labels.extend(countries)
plt.legend(handles=handles, labels=labels, framealpha=1.)
plt.show()
现在因为我们已经有了一个带有形状的多边形,为什么不通过直接将形状绘制到图例中来让图例更花哨一点。这可以按如下方式完成。
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import numpy as np
m = Basemap(llcrnrlon=-10,llcrnrlat=35,urcrnrlon=35,urcrnrlat=60.,
resolution='i', projection='tmerc', lat_0 = 48.9, lon_0 = 15.3)
m.drawcoastlines()
fn = r"ne_10m_admin_0_countries\ne_10m_admin_0_countries"
m.readshapefile(fn, 'shf', drawbounds = False)
#Madrid
x,y = m([-3.703889],[40.4125])
m.plot(x,y, marker="o", color="blue", label="Madrid", ls="")
countries = ['Switzerland', 'Ireland', "Belgium"]
colors= {'Switzerland':"red", 'Ireland':"orange", 'Belgium' : "purple"}
shapes = {}
for info, shape in zip(m.shf_info, m.shf):
if info['NAME'] in countries:
p= Polygon(np.array(shape), True, facecolor= colors[info['NAME']],
edgecolor='none', alpha=0.7, zorder=2)
shapes.update({info['NAME'] : p})
for country in countries:
plt.gca().add_artist(shapes[country])
class PolygonN(object):
def legend_artist(self, legend, orig_handle, fontsize, handlebox):
x0, y0 = handlebox.xdescent, handlebox.ydescent
width, height = handlebox.width, handlebox.height
aspect= height/float(width)
verts = orig_handle.get_xy()
minx, miny = verts[:,0].min(), verts[:,1].min()
maxx, maxy = verts[:,0].max(), verts[:,1].max()
aspect= (maxy-miny)/float((maxx-minx))
nvx = (verts[:,0]-minx)*float(height)/aspect/(maxx-minx)-x0
nvy = (verts[:,1]-miny)*float(height)/(maxy-miny)-y0
p = Polygon(np.c_[nvx, nvy])
p.update_from(orig_handle)
p.set_transform(handlebox.get_transform())
handlebox.add_artist(p)
return p
handles, labels = plt.gca().get_legend_handles_labels()
handles.extend([shapes[c] for c in countries])
labels.extend(countries)
plt.legend(handles=handles, labels=labels, handleheight=3, handlelength=3, framealpha=1.,
handler_map={Polygon: PolygonN()} )
plt.show()