cartopy学习
- cartopy简介
- cartopy绘制中国行政地图(cartopy的版本为0.20.0)
- cartopy绘制中国行政地图,单一省细分画出市区
- cartopy库的一些问题
cartopy简介
- cartopy是一个用于绘制地图投影和地理数据可视化的 Python 库。
- 它是建立在 matplotlib 的基础上,专门用于制作地图和地理数据的图表。
- cartopy 的目标是使地图制作变得更加简单和直观,同时提供了一些强大的功能来处理地理数据和投影。
cartopy绘制中国行政地图(cartopy的版本为0.20.0)
- 省界显示
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
fig = plt.figure(figsize=(12,8))
# 投影方式
crs = ccrs.PlateCarree()
ax = fig.add_subplot(111, projection=crs)
# 显示范围
extents = [70, 140, 0, 55]
ax.set_extent(extents, crs)
filepath = '.\bou2_4p.shp'
file_nineline = ".\九段线.shp"
reader = shpreader.Reader(filepath)
reader_nineline = shpreader.Reader(file_nineline)
geoms = reader.geometries()
geoms_nineline = reader_nineline.geometries()
# 绘制陆地和九段线
ax.add_geometries(geoms, crs, lw=0.5, fc='none')
ax.add_geometries(geoms_nineline, crs, lw=0.5, fc='none')
reader.close()
reader_nineline.close()
plt.show()
- 市级行政单位显示
# 在以上代码中添加市图层即可
city_files = shpreader.Reader(r'.\市.shp')
ax.add_geometries(city_files.geometries(), crs, lw=0.5, fc='none')
reader.close()
- 县级行政单位显示
# 在以上代码中添加市图层即可
county_files = shpreader.Reader(r'.\县.shp')
ax.add_geometries(county_file.geometries(), crs, lw=0.5, fc='none')
reader.close()
cartopy绘制中国行政地图,单一省细分画出市区
- 有时候我们仅仅关注一个省内细分的市区,而不关注其他省份,那么需要将单一省内的市边界画出
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
extents = [70, 140, 0, 55]
crs = ccrs.PlateCarree()
fig = plt.figure(figsize=(12,8))
ax = fig.add_subplot(111, projection=crs)
ax.set_extent(extents, crs)
city_reader = shpreader.Reader(r'.\市.shp')
reader = shpreader.Reader('.\bou2_4p.shp')
reader_nineline = shpreader.Reader(".\九段线.shp")
geoms = reader.geometries()
geoms_nineline = reader_nineline.geometries()
# 河南省市区
for record, geos in zip(city_reader.records(),city_reader.geometries()):
if record.attributes['省'] == '河南省':
ax.add_geometries([geos], crs, edgecolor='r', facecolor='none', lw=1)
records = city_reader.records()
# 中国地图
ax.add_geometries(geoms, crs, lw=0.5, fc='none')
ax.add_geometries(geoms_nineline, crs, lw=0.5, fc='none')
reader.close()
reader_nineline.close()
city_reader.close()
plt.show()
cartopy库的一些问题
- cartopy依赖于shapefile库读取文件,但是在初始化中只设置了一个参数,即文件的名称,没有不定参数的设定。这使得文档编码格式不是UTF-8类型的文件,读取出现乱码,无法使用关键字参数筛选数据。如图所示:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
import shapefile
filepath = '.\bou2_4p.shp'
x = shpreader.Reader(filepath)
for i in x.records():
print(i.attributes)
- shapefile源码中只设定了filename参数,没有不定参数的设定,导致无法选择encoding参数。
- 因此,在上述画图示例中,如果想使用关键字将“河南省”边界改变比较困难,因此,查看源码,使用以下方法进行修改,完成上述功能。
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
import shapefile
import shapely.geometry as sgeom
# 将shpreader中的geometries方法复制过来
def geometries(reader):
for shape in reader.iterShapes():
if shape.shapeType != shapefile.NULL:
yield sgeom.shape(shape)
extents = [70, 140, 0, 55]
crs = ccrs.PlateCarree()
fig = plt.figure(figsize=(12,8))
ax = fig.add_subplot(111, projection=crs)
ax.set_extent(extents, crs)
filepath = '.\bou2_4p.shp'
file_nineline = ".\九段线.shp"
# 直接使用shapefile进行文件读取
reader = shapefile.Reader(filepath, encoding="gbk")
reader_nineline = shpreader.Reader(file_nineline)
geoms = geometries(reader)
geoms_nineline = reader_nineline.geometries()
ax.add_geometries(geoms, crs, lw=0.5, fc='none')
ax.add_geometries(geoms_nineline, crs, lw=0.5, fc='none')
city_reader = shpreader.Reader(r'.\市.shp')
for record, geos in zip(city_reader.records(),city_reader.geometries()):
if record.attributes['省'] == '河南省':
ax.add_geometries([geos], crs, edgecolor='#733b97', facecolor='none', lw=1)
records = city_reader.records()
for record, geos in zip(reader.records(), geometries(reader)):
colors = {'河南省': "b", "河北省": "g", "山东省": 'r'}
if record.as_dict()['NAME'] in ['河南省', "河北省", "山东省"]:
ax.add_geometries([geos], crs, edgecolor=colors[record.as_dict()['NAME']], facecolor='none', lw=1)
records = city_reader.records()
reader.close()
city_reader.close()
reader_nineline.close()
plt.show()
- 使用关键字查看、进行数据筛选
for record, geos in zip(reader.records(), geometries(reader)):
print(record)