Cartopy绘图入门指南

这篇具有很好参考价值的文章主要介绍了Cartopy绘图入门指南。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

嗨,你好,我是来自点点GIS的南南

我与Cartopy的认识起源于“气象水文科研猫”的这个推文,那时候的我觉得,用代码画地图好酷,arcgis就感觉low爆了。但是一直没有时间学习。前段时间放暑假,磕磕绊绊装完包以后就不想动弹了,折腾环境折腾的我头皮发麻。gdal和cartopy真的是我学python以来装的最麻烦的包。

很多时候我想学习,却感觉无从下手,大佬们的博文一大堆,我看了以后只有一句“卧槽,牛逼”,然后没然后了。前几天某人欺负我,把我整抑郁了,大晚上睡不着觉,就想着填个坑,虽然我技术菜,不能“炫技”,但写个入门教程难不倒我吧。然后就有了这篇文章。

这篇文章参考了诸多大佬的博文,如气象学家,云台书使,气象学人,好奇心Log,等等公众号大佬。我作为初学者,写的文肯定错误不少,欢迎大家给我留言指正,要是有老板叫我去打工就更好了,嘿嘿嘿

Emil:2531788189@qq.com

Cartopy介绍

Cartopy 是一个开源免费的第三方 Python 扩展包,由英国气象办公室的科学家们开发,支持 Python 2.7 和 Python 3,致力于使用最简单直观的方式生成地图,并提供对 matplotlib 友好的协作接口。

在常用的python绘图库中,basemap,geopandas,pyecharts等,其中basemap已经停止维护了,在前文中我已经讲到过,pyecharts是用于数据可视化等专业图表的绘制,之前我的文章也介绍过,pyecharts在地学可视化中功能实在过于简陋;geopandas是基于pandas的,一般用于商业数据分析,所以我更推荐大家学习Cartopy,虽然Cartopy气象专业用得很多哈哈哈

Cartopy安装

https://mp.weixin.qq.com/s/GW6odDBGLPVRZTKx0YZLVg

Cartopy绘图入门

在Cartopy的使用过程中,我们常常需要搭配其他库一起使用,常用的有如Matplotlib ,numpy,pandas,gma等

Cartopy投影

Cartopy 是利用 Matplotlib 来画图的,因此首先要导入 pyplot 模块。在 Cartopy 中,每种投影都是一个类,被存放在 cartopy.crs 模块中,crs 即坐标参考系统(Coordinate Reference Systems)之意。所以接着要导入这个模块。

投影用法示例:

proj = ccrs.PlateCarree()   #proj = ccrs.投影()

这里简单说明一下常用的三种投影,Cartopy 大概有三四十种投影,如国想详细了解可以参考下面的文章

https://scitools.org.uk/cartopy/docs/v0.15/crs/projections.html
默认投影 PlateCarree
墨卡托投影 Mercator
兰勃脱投影 Lambert

默认投影适合单独省份或者地级市的绘制,兰勃脱投影适合中纬度大范围绘制,比如绘制全中国大公鸡、东亚形势、西北太平洋等;墨卡托投影适合低纬度赤道附近的绘制,一般研究台风、纬向环流等

绘制地图示例

将 cartopy 集成到 matplotlib 的主要类是 GeoAxes,它是普通 matplotlib Axes 的子类。GeoAxes 类为特定于绘制地图的轴添加了额外的功能。创建一个 GeoAxes 对象的办法是,在创建 axes(或 subplot)时,通过参数 projection 指定一个 ccrs 中的投影。这里便利用这一方法生成了一个等距圆柱投影下的 ax。

最后调用 ax 的方法 coastlines 画出海岸线,默认以本初子午线为中心,比例尺为 1:110m(m 表示 million)。

因此用 Cartopy 画地图的基本流程并不复杂:

  • 创建画布。

  • 通过指定 projection 参数,创建 GeoAxes 对象。

  • 调用 GeoAxes 的方法画图。

  • GeoAxes 用法扩展(部分常用)
    • set_global:让地图的显示范围扩展至投影的最大范围。例如,对 PlateCarree 投影的 ax 使用后,地图会变成全球的。
    • set_extent:给出元组 (x0, x1, y0, y1) 以限制地图的显示范围。
    • set_xticks:设置 x 轴的刻度。
    • set_yticks:设置 y 轴的刻度。
    • gridlines:给地图添加网格线。
    • coastlines:在地图上绘制海岸线。
    • stock_img:给地图添加低分辨率的地形图背景。
    • add_feature:给地图添加特征(例如陆地或海洋的填充、河流等)。
import matplotlib.pyplot as plt###引入库包
import cartopy.crs as ccrs
proj = ccrs.PlateCarree()
fig = plt.figure(figsize=(4, 4), dpi=200)  # 创建画布
ax = plt.axes(projection=ccrs.PlateCarree())# 创建子图
ax.coastlines()# 调用ax的方法画海岸线
'''
fig语法:
figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True)
num:图像编号或名称,数字为编号 ,字符串为名称
figsize:指定figure的宽和高,单位为英寸;
dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80      1英寸等于2.5cm,A4纸是 21*30cm的纸张 
facecolor:背景颜色
edgecolor:边框颜色
frameon:是否显示边框
'''

Cartopy绘图入门指南

如需修改中央经线,可以在创建子图的时候指定一些参数

ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))#全球图像的中央位于太平洋的 180 度经线处

Cartopy绘图入门指南

也可以在绘制线条的时候指定线宽

ax.coastlines(lw=0.3)#线条宽度0.3

Cartopy绘图入门指南

在地图上添加特征

上面的地图是一个十分粗糙的地图,仅有海岸线,尝试一下添加更多地理信息

添加预定义要素

首先需要导入一个cartopy.feature 常量,为了简化一些非常常见的情况,如大陆海洋国界等cartopy都已经进行了预定义,但需要注意的是直接导入的中国国界线并不是标准的,在使用时需要注意

这些信息带有三种分辨率,分别为110m,50m和10m。

Cartopy绘图入门指南

import matplotlib.pyplot as plt###引入库包
import cartopy.crs as ccrs
import cartopy.feature as cfeature#预定义常量

proj = ccrs.PlateCarree()
fig = plt.figure(figsize=(4, 4), dpi=200)  # 创建画布
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))#全球图像的中央位于太平洋的 180 度经线处

ax.add_feature(cfeature.LAND)#添加陆地
ax.add_feature(cfeature.COASTLINE,lw = 0.3)#添加海岸线
ax.add_feature(cfeature.RIVERS,lw = 0.25)#添加河流
#ax.add_feature(cfeat.RIVERS.with_scale('50m'),lw = 0.25)  # 加载分辨率为50的河流
ax.add_feature(cfeature.LAKES)#添加湖泊
ax.add_feature(cfeature.BORDERS, linestyle = '-',lw = 0.25)#不推荐,因为该默认参数会使得我国部分领土丢失
ax.add_feature(cfeature.OCEAN)#添加海洋

ax.coastlines(lw=0.3)

Cartopy绘图入门指南

在cartopy中,所有的线条都可以改变他的粗细。只用改变其参数lw = *即可

ax.add_feature(cfeature.RIVERS,lw = 2)#改变河流粗细

Cartopy绘图入门指南

同样的,所有的线,面也可以改变它的颜色

ax.add_feature(cfeature.LAKES,color='r')#指定湖泊颜色为红色

Cartopy绘图入门指南

添加经纬度标签

这里还是要用到前文说过的GeoAxes 用法

  • set_xticks:设置 x 轴的刻度。
  • set_yticks:设置 y 轴的刻度。

例:x轴为(-180,-120,-60,0,60,120,180),y轴为(-90,-60, -30, 0, 30, 60,90)

x_extent = [ 0, 60, 120, 180, 240, 300, 360]#经纬度范围,#直接使用(-180,-120,-60,0,60,120,180)会异常,需要写成(0, 60, 120, 180, 240, 300, 360)的形式
y_extent = [ -90,-60, -30, 0, 30, 60,90]

fig = plt.figure(figsize=(4, 4), dpi=200)  
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))

ax.add_feature(cfeature.LAND)#添加陆地
ax.add_feature(cfeature.COASTLINE,lw = 0.3)#添加海岸线
ax.add_feature(cfeature.RIVERS,lw = 0.25)#添加河流
ax.add_feature(cfeature.LAKES)#指定湖泊颜色为红色#添加湖泊
#ax.add_feature(cfeature.BORDERS, linestyle = '-',lw = 0.25)#不推荐,因为该默认参数会使得我国部分领土丢失
ax.add_feature(cfeature.OCEAN)#添加海洋

ax.set_xticks(x_extent, crs=ccrs.PlateCarree())#添加经纬度
ax.set_yticks(y_extent, crs=ccrs.PlateCarree())

Cartopy绘图入门指南

将经纬度标签转换为具有单位的形式

from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter #导入Cartopy专门提供的经纬度的Formatter

x_extent = [ 0, 60, 120, 180, 240, 300, 360]#经纬度范围,#直接使用(-180,-120,-60,0,60,120,180)会异常,需要写成(0, 60, 120, 180, 240, 300, 360)的形式
y_extent = [ -90,-60, -30, 0, 30, 60,90]

fig = plt.figure(figsize=(4, 4), dpi=200)  
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))

ax.add_feature(cfeature.LAND)#添加陆地
ax.add_feature(cfeature.COASTLINE,lw = 0.3)#添加海岸线
ax.add_feature(cfeature.RIVERS,lw = 0.25)#添加河流
ax.add_feature(cfeature.LAKES)#指定湖泊颜色为红色#添加湖泊
#ax.add_feature(cfeature.BORDERS, linestyle = '-',lw = 0.25)#不推荐,因为该默认参数会使得我国部分领土丢失
ax.add_feature(cfeature.OCEAN)#添加海洋

ax.set_xticks(x_extent, crs=ccrs.PlateCarree())#添加经纬度
ax.set_yticks(y_extent, crs=ccrs.PlateCarree())

# 利用Formatter格式化刻度标签
lon_formatter = LongitudeFormatter(zero_direction_label=False)
lat_formatter = LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)

Cartopy绘图入门指南

经纬网

在前文中GeoAxes 用法提到过添加经纬网的函数gridlines,只用在上述代码末尾中添加ax.gridlines(),即

ax.gridlines()#添加网格

Cartopy绘图入门指南

这实在是太丑了,给它换个线样式

ax.gridlines(linestyle='--')#添加网格,线样式为'--'

Cartopy绘图入门指南

配上网格总感觉刻度朝外怪怪的

ax.tick_params(color = 'blue',direction='in')#更改刻度指向为朝内,颜色设置为蓝色

Cartopy绘图入门指南

更多GeoAxes 用法可以参考以下文章

https://scitools.org.uk/cartopy/docs/v0.14/matplotlib/feature_interface.html

局部地图

很多时候我们绘图不会用到世界地图,所以可以尝试更改你的范围。cartopy提供更改的方式是通过定义经纬度范围来进行更改的。在上述代码末尾添加下方样例代码试试

set_extent:给出元组 (x0, x1, y0, y1) 以限制地图的显示范围。

ax.set_extent([0,180,0,35],crs = ccrs.PlateCarree()) #选取经度为0°E-180°E,纬度为0°N-90°N的区域

Cartopy绘图入门指南

添加标题

ax.set_title('Cartopy') #添加标题Cartopy

Cartopy绘图入门指南

Cartopy绘图进阶

在前文中提到过,Cartopy的中国地图边界是有问题的,那么在日常使用中,我们该如何避免这些问题呢?

Cartopy中国地图绘制方法

方法一

用 Cartopy 的 shapereader 读取后即可绘制。 Cartopy 的 shapereader用法示例可参考以下文章

https://scitools.org.uk/cartopy/docs/v0.15/tutorials/using_the_shapereader.html

关于正确的行政边界获取可以参考以下博文

https://mp.weixin.qq.com/s/aUCjTRrV6Cz-k7mtXOEiGw

使用cartopy读取shapefile绘制共有两种方法,分别是add_featureadd_geometries,但无论你使用哪种方法,你都需要先读取文件才能够添加。Cartopy提供了一个基于pyshp的接口以实现对地理文件的简单读取和操作:

首先导入相关包

import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.feature as cfeat
import cartopy.io.shapereader as shapereader

你找他总得给他来一个地址吧

shp_path = "D:/data2/china/china/province_9south.shp"#切记路径一定要英文,血的教训!!!

绘图三部曲,画布,投影,子图

fig  = plt.figure(figsize=(6,6)) #创建画布
proj = ccrs.PlateCarree()#创建投影,选择cartopy的默认投影
ax   = fig.subplots(1, 1, subplot_kw={'projection': proj})  #子图
extent = [70,140,2,60]#限定绘图范围
add_feature加载自定义地图
china_map = cfeat.ShapelyFeature(shapereader.Reader(china_map).geometries(), proj, edgecolor='k', facecolor='none')
ax.add_feature(china_map, linewidth=1)
ax.set_extent(extent, crs=proj)

Cartopy绘图入门指南

add_geometries加载自定义地图
ax.add_geometries(shapereader.Reader(china_map).geometries(), crs=proj, facecolor='none',edgecolor='k',linewidth=1)
ax.set_extent(extent, crs=proj)

Cartopy绘图入门指南

完整代码如下
import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.feature as cfeat
import cartopy.io.shapereader as shapereader

shp_path = "D:/data2/china/china/province_9south.shp"#切记路径一定要英文,血的教训!!!

fig  = plt.figure(figsize=(6,6)) #创建画布
proj = ccrs.PlateCarree()#创建投影,选择cartopy的默认投影
ax   = fig.subplots(1, 1, subplot_kw={'projection': proj})  #子图
extent = [70,140,2,60]#限定绘图范围

china_map = cfeat.ShapelyFeature(shapereader.Reader(shp_path).geometries(), proj, edgecolor='k', facecolor='none')
ax.add_feature(china_map, linewidth=1)#添加读取的数据,设置线宽
ax.set_extent(extent, crs=proj)

#ax.add_geometries(shapereader.Reader(shp_path).geometries(), crs=proj, #facecolor='none',edgecolor='k',linewidth=1)
#ax.set_extent(extent, crs=proj)
方法二

使用GMT 中文社区上提供的省界的经纬度数据进行绘图。GMT 中文社区为用户提供了一套名为CN-border的基本准确的数字化中国国界,、省界数据。在此向 GMT 中文社区的维护和贡献者表示感谢!

但需要注意的是,即便正确绘制了国界、省界,所绘地图如果要在境内公开展示,依然需要审图。个人没有提交审图申请的资格,需要付费,委托给有资质的企事业单位代为提交审图申请。下为GMT 中文社区网址,大家可自行下载

https://docs.gmt-china.org/latest/dataset-CN/CN-border/

CN-border 数据提供了三个数据文件:

  • CN-border-La.gmt:中国国界、省界、十段线以及南海诸岛数据
  • CN-border-L1.gmt:中国国界、十段线以及南海诸岛数据,不含省界数据
  • ten-dash-line.gmt:仅十段线数据
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature

#加载边界数据,CN-border-La.dat下载
#https://github.com/gmt-china/china-geospatial-data/releases
with open('C:/Users/啊啊啊啊/Desktop/china-geospatial-data-GB2312/CN-border-La.gmt') as src:
    context = src.read()
    blocks = [cnt for cnt in context.split('>') if len(cnt) > 0]
    borders = [np.fromstring(block, dtype=float, sep=' ') for block in blocks]

# 画布
fig = plt.figure(figsize=[10, 8])
# 设置投影并绘制主图形
ax = plt.axes(projection=ccrs.LambertConformal(central_latitude=90,
                                               central_longitude=105))
# 绘制线条
for line in borders:
    ax.plot(line[0::2], line[1::2], '-', lw=1, color='k',
            transform=ccrs.Geodetic())
# 绘制边界线
for line in borders:
    sub_ax.plot(line[0::2], line[1::2], '-', lw=1, color='k',
                transform=ccrs.Geodetic())
# 设置图形范围
sub_ax.set_extent([105, 125, 0, 25])
# 显示图形
plt.show()

Cartopy绘图入门指南

方法三

cnmaps绘图,cnmaps是Cartopy的一个扩展包,内置了中国地图数据源,该数据源自高德地图API,大家可以自行去该项目进行学习

https://github.com/Clarmy/cnmaps

重点区域突出显示

该示例是在前文方法一的基础上进行绘制

Cartopy 默认对所有地物使用相同的外观,如果需要突出显示某些地物,就必须进行筛选。这里从province_9south.shp这份全国省级行政区划数据中选中山西(通过属性表SHENG_ID字段),然后使用 ax.add_geometries() 方法将它们加入到原有地图元素中。

for state, geos in zip(shapereader.Reader(shp_path).records(), shapereader.Reader(shp_path).geometries()) :
    if state.attributes['SHENG_ID'] in [14 ]:#如果'14'在'SHENG_ID'这个字段中
        ax.add_geometries([geos], crs=proj,facecolor='None', edgecolor='blue')  # 重点区域上色

Cartopy绘图入门指南

关于属性表,你可以通过gdal来打印出该shpfile文件所具有的属性表,也可以通过arcgis,qgis等GIS软件打开查询

仅绘制山西省

注意在前文中我加粗的那个词“加入”这意味着上文中重点区域突出显示的山西省图层是经过筛选而添加到地图中的,而不是对山西省这个范围进行符号化,如果我们要只显示山西省的话,就将上述代码中显示全国范围的代码注释掉即可,参见下方示例代码

fig = plt.figure(figsize=(6,6))  
ax = fig.subplots(1, 1, subplot_kw={'projection': proj})  
#ax.add_geometries(shapereader.Reader(shp_path).geometries(), crs=proj,facecolor='none',edgecolor='k',linewidth=1)
ax.set_extent(extent, crs=proj)

for state, geos in zip(shapereader.Reader(shp_path).records(), shapereader.Reader(shp_path).geometries()) :
    if state.attributes['SHENG_ID'] in [14]:
        ax.add_geometries([geos], crs=proj,facecolor='None', edgecolor='red')  # 重点区域上色

Cartopy绘图入门指南

添加南海小地图

在之前的的学习中我们知道,cartopy绘制的地图称为子图,在绘制中国地图时候,有时候由于地图大小的限制,我们无法展示部分地区如南海,常规的方法是绘制两幅地图,比如一张为全国地图,一张为局部地图,也就是常说的南海小地图。

常见的subplot和subplot2grid函数一般来说绘制的地图大小是一样的,不容易展示比例大小,所以我们选择add_axes()命令来绘制两个大小不一样的子图。需要注意的是在绘制时我们需要定义两个extent参数,即分别为总的地图和南海小地图分别定义画布大小绘图范围

extent = [105, 133, 15, 45]#限定绘图范围

fig = plt.figure(figsize=(6,8))  #注意画布大小
ax = fig.subplots(1, 1, subplot_kw={'projection': proj})  
ax.add_geometries(shapereader.Reader(shp_path).geometries(), crs=proj,facecolor='none',edgecolor='k',linewidth=1)
ax.set_extent(extent, crs=proj)

left, bottom, width, height = 0.67, 0.16, 0.23, 0.27#南海小地图大小
ax2 = fig.add_axes([left, bottom, width, height], projection=proj)
ax2.add_geometries(shapereader.Reader(shp_path).geometries(), crs=proj, facecolor='none',edgecolor='k',linewidth=1)
ax2.set_extent([105, 125, 0, 25])#注意南海小地图的范围

Cartopy绘图入门指南

添加地形图背景

一个简单的尝试

在看完了上述内容后还是觉得有些不足,让我们结合来Cartopy绘图入门中所讲述的内容来给他添加一个背景吧

import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.feature as cfeature
import cartopy.io.shapereader as shapereader

shp_path = "D:/data2/china/china/province_9south.shp"#切记路径一定要英文,血的教训!!!

fig = plt.figure(figsize=(6,8))  #注意画布大小
proj = ccrs.PlateCarree()#创建投影,选择cartopy的默认投影
ax   = fig.subplots(1, 1, subplot_kw={'projection': proj})  #子图
extent = [105, 133, 15, 45]#限定绘图范围

ax = fig.subplots(1, 1, subplot_kw={'projection': proj})  
ax.add_geometries(shapereader.Reader(shp_path).geometries(), crs=proj,facecolor='none',edgecolor='k',linewidth=1)
ax.set_extent(extent, crs=proj)
#添加其他要素
ax.add_feature(cfeature.OCEAN.with_scale('50m'))
ax.add_feature(cfeature.LAND.with_scale('50m'))
ax.add_feature(cfeature.RIVERS.with_scale('50m'))
ax.add_feature(cfeature.LAKES.with_scale('50m'))

left, bottom, width, height = 0.67, 0.16, 0.23, 0.27#南海小地图大小
ax2 = fig.add_axes([left, bottom, width, height], projection=proj)
ax2.add_geometries(shapereader.Reader(shp_path).geometries(), crs=proj, facecolor='none',edgecolor='k',linewidth=1)
ax2.set_extent([105, 125, 0, 25])#注意南海小地图的范围

Cartopy绘图入门指南

这时候我们会疑惑,为什么南海小地图还是这样。在上文中提到过,南海小地图是另一幅地图,他与原来的中国地图你可以理解为是两幅地图。所以也需要在南海小地图中添加要素,也就是ax2中

import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.feature as cfeature
import cartopy.io.shapereader as shapereader

shp_path = "D:/data2/china/china/province_9south.shp"#切记路径一定要英文,血的教训!!!

fig = plt.figure(figsize=(6,8))  #注意画布大小
proj = ccrs.PlateCarree()#创建投影,选择cartopy的默认投影
ax   = fig.subplots(1, 1, subplot_kw={'projection': proj})  #子图
extent = [105, 133, 15, 45]#限定绘图范围

ax = fig.subplots(1, 1, subplot_kw={'projection': proj})  
ax.add_geometries(shapereader.Reader(shp_path).geometries(), crs=proj,facecolor='none',edgecolor='k',linewidth=1)
ax.set_extent(extent, crs=proj)
#添加其他要素_中国地图
ax.add_feature(cfeature.OCEAN.with_scale('50m'))
ax.add_feature(cfeature.LAND.with_scale('50m'))
ax.add_feature(cfeature.RIVERS.with_scale('50m'))
ax.add_feature(cfeature.LAKES.with_scale('50m'))

left, bottom, width, height = 0.67, 0.16, 0.23, 0.27#南海小地图大小
ax2 = fig.add_axes([left, bottom, width, height], projection=proj)
ax2.add_geometries(shapereader.Reader(shp_path).geometries(), crs=proj, facecolor='none',edgecolor='k',linewidth=1)
ax2.set_extent([105, 125, 0, 25])#注意南海小地图的范围
#添加其他要素_南海小地图
ax2.add_feature(cfeature.OCEAN.with_scale('50m'))
ax2.add_feature(cfeature.LAND.with_scale('50m'))
ax2.add_feature(cfeature.RIVERS.with_scale('50m'))
ax2.add_feature(cfeature.LAKES.with_scale('50m'))

Cartopy绘图入门指南

添加图片作为背景
方法一

使用cartopy的add_image方法,这里以添加osm在线地图的图片为例子

imagery = OSM()
ax.add_image(imagery, 4)#四为影像级别

Cartopy绘图入门指南

完整代码如下

import cartopy.crs as ccrs
import cartopy.feature as cfeat
from cartopy.io.shapereader import Reader
import matplotlib.pyplot as plt
from matplotlib.image import imread
from cartopy.io.img_tiles import OSM

def create_map():
    # --设置shp路径,数据集已公开
    shp_path = 'D:/data2/china/china/province_9south.shp'
    # --设置tif路径,数据集已公开
    tif_path = 'D:/data2/china/china/NE1_50M_SR_W.tif'
    # --创建画图空间
    proj = ccrs.PlateCarree()  # 创建坐标系
    fig = plt.figure(figsize=(6, 8))  # 创建页面
    ax = fig.subplots(1, 1, subplot_kw={'projection': proj})  

    # --设置地图属性
    provinces = cfeat.ShapelyFeature(Reader(shp_path).geometries(),proj, edgecolor='k',facecolor='none')
    # --加载省界线
    ax.add_feature(provinces, lw=0.6, zorder=2)
    ax.set_extent([105, 133, 15, 45])  #可根据需求自行定义
   #添加osm图片
    imagery = OSM()
    ax.add_image(imagery, 4)#四为影像级别
ax = create_map()
plt.show()
方法二

添加图片所使用的第二种方法是 ax.imshow,是基于matplotlib的,这里以加载地形图图片为例

ax.imshow(imread(tif_path),extent=[-180, 180, -90, 90])注意范围

Cartopy绘图入门指南

绘制的完整代码如下:

import cartopy.crs as ccrs
import cartopy.feature as cfeat
from cartopy.io.shapereader import Reader
import matplotlib.pyplot as plt
from matplotlib.image import imread

def create_map():
    # --设置shp路径,数据集已公开
    shp_path = 'D:/data2/china/china/province_9south.shp'
    # --设置tif路径,数据集已公开
    tif_path = 'D:/data2/china/china/NE1_50M_SR_W.tif'
    # --创建画图空间
    proj = ccrs.PlateCarree()  # 创建坐标系
    fig = plt.figure(figsize=(6, 8))  # 创建页面
    ax = fig.subplots(1, 1, subplot_kw={'projection': proj})  

    # --设置地图属性
    provinces = cfeat.ShapelyFeature(Reader(shp_path).geometries(),proj, edgecolor='k',facecolor='none')
    # --加载省界线
    ax.add_feature(provinces, lw=0.6, zorder=2)
    ax.set_extent([105, 133, 15, 45])  #可根据需求自行定义
    # ax.stock_img()  ##可直接使用低分辨率背景
    # --加载高分辨率地形
    ax.imshow(imread(tif_path),extent=[-180, 180, -90, 90])
ax = create_map()
plt.show()

你可以试试结合上述所讲的内容,做出一副这样的地图

Cartopy绘图入门指南

示例代码如下:

import cartopy.crs as ccrs
import cartopy.feature as cfeat
from cartopy.io.shapereader import Reader
import matplotlib.pyplot as plt
from matplotlib.image import imread

def create_map():
    # --设置shp路径,数据集已公开
    shp_path = 'D:/data2/china/china/province_9south.shp'
    # --设置tif路径,数据集已公开
    tif_path = 'D:/data2/china/china/NE1_50M_SR_W.tif'
    # --创建画图空间
    proj = ccrs.PlateCarree()  # 创建坐标系
    fig = plt.figure(figsize=(6, 8))  # 创建页面
    ax = fig.subplots(1, 1, subplot_kw={'projection': proj})  

    # --设置地图属性
    provinces = cfeat.ShapelyFeature(Reader(shp_path).geometries(),proj, edgecolor='k',facecolor='none')
    # --加载省界线
    ax.add_feature(provinces, lw=0.6, zorder=2)
    ax.set_extent([105, 133, 15, 45])  #可根据需求自行定义
    # ax.stock_img()  ##可直接使用低分辨率背景
    # --加载高分辨率地形
    ax.imshow(imread(tif_path),origin='upper', transform=proj,extent=[-180, 180, -90, 90])
    # --设置网格点属性
    gl = ax.gridlines(crs=ccrs.PlateCarree(),draw_labels=True,linewidth=1.2,color='k',alpha=0.5,linestyle='--')
    # --设置南海子图
    left, bottom, width, height = 0.67, 0.16, 0.23, 0.27
    ax2 = fig.add_axes([left, bottom, width, height], projection=proj)
    ax2.add_feature(provinces, linewidth=0.6, zorder=2)
    ax2.set_extent([105, 125, 0, 25])
    # ax2.stock_img()  ##可直接使用低分辨率背景
    # --加载高分辨率地形
    ax2.imshow(imread(tif_path),origin='upper',transform=proj,extent=[-180, 180, -90, 90])
    return ax
ax = create_map()
plt.show()

注:本例教程参考至和鲸大佬【大自然搬运工】,针对大佬的代码做了一些简化方便大家理解;大佬绘制经纬网好像使用的是matplotlib库,与我之前所讲述的cartopy库绘制不一样。原文章如下:

https://www.heywhale.com/mw/project/5f3c95a3af3980002cbf560b

学习心得

本文作为基础入门教程就写到这里吧,这几天学习强度有点大了。在本文的学习过程中,我在和鲸社区找到了大量优质的学习博文,十分建议大家可以去看一看,同时以也才cartopy的文档里得到了非常多的帮助,里面还有很多地图的绘制方式,如果有机会,我希望我可以学习一下。文章来源地址https://www.toymoban.com/news/detail-460727.html

和鲸社区
https://www.heywhale.com/home
cartopyAPI参考
https://scitools.org.uk/cartopy/docs/latest/reference/generated/cartopy.mpl.geoaxes.GeoAxes.html#cartopy.mpl.geoaxes.GeoAxes.add_feature
cartopy更多地图
https://scitools.org.uk/cartopy/docs/latest/gallery/index.html

数据下载

行政区划_省界.shp

https://wwc.lanzouw.com/iQ4TT0843gpc

GMT 中文社区提供的数据

https://wwc.lanzouw.com/iYLrc0843gvi

地形图图片

https://wwc.lanzouw.com/ipPrM0843g8f

参考文档

https://zhajiman.github.io/post/cartopy_introduction/
https://mp.weixin.qq.com/s/FKNBOD2Yo4sawWTO76zZgA
https://mp.weixin.qq.com/s/m4Ao0--o1umSICEWO9UlKw
https://mp.weixin.qq.com/s/oe2ncVdqfdjaPSDZ2-YLQg
https://cloud.tencent.com/developer/article/1790590
https://mp.weixin.qq.com/s/wbyrkmVoaWgz6MdBI_6BZg
https://mp.weixin.qq.com/s/5RiuM2AQxNIvgNcLf5fCDw
https://mp.weixin.qq.com/s/FGCPIoiC5OUkGGf_IreWZQ
https://www.cnblogs.com/youxiaogang/p/14247184.html
https://www.heywhale.com/mw/project/629eefe52d8168866e54adc9
https://www.heywhale.com/mw/project/5f1a4df794d484002d2db14a
https://www.heywhale.com/mw/project/5f3c95a3af3980002cbf560b
https://blog.csdn.net/m0_37362454/article/details/81511427
https://www.osgeo.cn/pygis/cartopy-feature.html
https://vimsky.com/examples/detail/python-module-cartopy.mpl.ticker.html
https://scitools.org.uk/cartopy/docs/v0.14/matplotlib/feature_interface.html
https://mp.weixin.qq.com/s/jpZOpnFvMwi4ZTafflXIzw
https://gnss.help/2018/04/24/cartopy-gallery/index.html
https://blog.csdn.net/weixin_42372313/article/details/113572786
https://scitools.org.uk/cartopy/docs/latest/index.html
https://scitools.org.uk/cartopy/docs/v0.13/matplotlib/geoaxes.html
https://waterhackweek.github.io/visualization/04-geopandas-and-cartopy/
https://scitools.org.uk/cartopy/docs/v0.14/matplotlib/feature_interface.html
https://mp.weixin.qq.com/s/ASV-VI6gfbea90vtJbdpIw

到了这里,关于Cartopy绘图入门指南的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (入门向)面向萌新的算法比赛入门指南

    算法是指解决问题或完成特定任务的一系列明确指令或步骤集合。它是一个定义良好、逐步执行的操作序列,用于将输入转换为输出。算法可用于计算、数据处理、自动化控制、问题解决等各个领域。 算法通常由一系列简单的操作组成,这些操作可以是基本的数学运算、逻辑

    2024年02月07日
    浏览(48)
  • 程序员入门指南

    本文作者:futz12 ,szx0427 虽然本人由于多方面原因没有选择计科/软工(对AI和图形算法的热爱),但是根据多年研究经验(业余的),打算给各位推荐基本相关的书和软件(主要是学习思路)。 注意:学习编程不一定是搞那些绚丽的界面,开发有趣的游戏。很多有用且享誉世

    2024年02月14日
    浏览(63)
  • 【Postman入门指南】

    前言 Postman 提供了测试 API 的友好界面和功能,使用简单便捷,安全可靠。 目录 前言 一、Postman安装 二、Postman的基础功能 三、Postman的进阶功能 一、Postman安装 1、Postman安装 Postman在2018年之后不再支持浏览器版本,下载客户端,安装即可使用。 下载网址:Download Postman | Get

    2024年02月04日
    浏览(41)
  • Flutter入门指南

    笔者项目中使用Flutter的模块并不多。虽然笔者还没有机会在项目中正式使用Flutter,但是也在学习Flutter的一些基本用法。本文就是一篇Flutter的入门介绍,后续会写更多深入介绍的文章。Flutter可以通过一套代码库快速构建高质量、高性能的跨平台应用,支持iOS、Android、Web以及

    2024年04月10日
    浏览(43)
  • IOS小白入门指南

            加入ios 项目已经一个多月了,本篇文章主要介绍IOS开发入门的一些基础知识,帮助想学习iOS开发的人更有效率地学习。 目录 需要的计算机基础    开发语言选择 IOS两种开发语言的异同 Objective-C和swift的相同点: 二者的不同点: 开发环境---XCode介绍 基本信息 S

    2024年02月01日
    浏览(36)
  • Go 语言入门指南

    学一门语言先看看helloworld吧,感觉go结合了好多语言的方式,写起来一会像python一会像c++,java差不多。反正语法挺奇特 go语言特点: 高性能、高并发 语法简单,学习曲线平缓 丰富的标准库 完善的工具链 静态链接 快速编译 跨平台 垃圾回收 首先听到老师说 go语言编译贼快,

    2024年02月15日
    浏览(43)
  • HTML 入门指南

    参考:HTML 教程- (HTML5 标准) HTML:超级文本标记语言(HyperText Markup Language) “超文本” 就是指页面内可以包含图片、链接等非文字内容。 “标记” 就是使用标签的方法将需要的内容包括起来。例如: a herf=\\\"sfdsfsd\\\"www.itcast.cn/a img/ HTML 用于 编写网页 。平时上网通过浏览器看到

    2024年02月20日
    浏览(34)
  • RabbitMQ入门指南

    提供了系统之间的异步调用,比如一个支付功能,用户在支付完成之后,会去数据库中执行后续操作,然后更新支付状态,会生成订单信息,如果后续还需要添加功能,就需要去业务逻辑中修改代码,这样就会出现业务耦合。同时想要执行后续操作,需要等待支付功能完成,

    2024年02月21日
    浏览(79)
  • ES入门指南

    前言 本文章适用于未接触ES或接触较少的中高级开发工程师,以较低的学习成本,快速学习ES并在生产中应用为核心目的 本文章主要以实战维度展开,在不影响数据安全以及基本的性能危机的前提下,不会过多的涉及深层次的底层原理(但也会涉及一些基本的原理,防止出现类

    2023年04月08日
    浏览(60)
  • 谷歌Bard入门指南

    Bard 是一个大型语言模型,也称为对话式 AI 或聊天机器人,经过训练,内容丰富且全面。Bard 接受过大量文本数据的培训,能够针对各种提示和问题进行交流并生成类似人类的文本。例如,Bard 可以提供事实主题的摘要或创建故事。 看起来不错哟。你猜的没错,这就是他自己

    2024年02月12日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包