相关文章推荐
豁达的帽子  ·  Dbeaver无法连接 - CSDN文库·  4 月前    · 

1、Cartopy包的安装

通过pip来下载安装,在cmd命令行下输入 pip install cartopy ,可直接下载安装cartopy及其依赖包。
在编辑器PyCharm中下载安装:
在这里插入图片描述
注:在首先下载时,我用Python的是3.10版本,下载失败了。后面我就先把一些依赖包提前下载好,再去下载cartopy包依然没成功。后面参考了这篇文章:
博客【在Python下载cartopy库以及地图文件存放的问题】 ,换用python3.9.7的环境来下载安装cartopy包,成功了!

2、Cartopy包基础学习

1.坐标参考系

地图绘制涉及坐标参考系(coordinate reference system,crs),同个数据,采用不同坐标参考系统绘制的地图是不同的。
cartopy包中的 crs模块 定义了20多个常用的坐标参考系统类(利用 proj包 ),用于创建不同的crs对象。
【PS:PROJ.4是开源GIS最著名的地图投影库,它专注于地图投影的表达,以及转换,许多GIS开源软件的投影都直接使用Proj.4的库文件。
https://www.osgeo.cn/pygis/proj-projintro.html

cartopy定义的主要坐标参照系统类

坐标参照系统类 解释
PlateCarree 把经纬度的值作为x,y坐标值
AlbersEqualArea 阿伯斯等积圆锥投影
LambertConformal 兰伯特等角圆锥投影
Mercator 墨卡托投影(正轴圆柱投影)
UTM 通用横轴墨卡托投影(分带投影)

同时,在创建坐标参照系统对象时,可以通过 关键字参数 设置坐标参照系统参数。常用的关键字参数有:

  • central_longitude(中央经线)
  • central_latitude(中央纬线)
  • standard_parallels(标准纬线)
  • globe(大地测量基准)

创建crs对象的一些示例:

cartopy.crs.PlateCarree(central_longitude=180)
cartopy.crs.LambertConformal(central_longitude=110)
cartopy.crs.AlbersEqualArea(central_longitude=105.0, standard_parallels=(25.0, 45.0))
cartopy.crs.UTM(zone=30)

2.加载空间数据

绘制前提(Geoaxes对象的创建):
当创建绘图区域(axes类)时,可以定义projection关键字参数。当projection关键字参数的值是crs对象时,这是返回的对象是Geoaxes对象

fig = plt.figure()  # 创建Figure对象
crs = ccrs.PlateCarree()  # 创建crs对象
ax = fig.add_subplot(2, 1, 1, projection=crs)  # 通过添加projection参数 创建geoaxes对象
print(ax)  
'''返回:< GeoAxes: <cartopy.crs.PlateCarree object at 0x000002AE4C56AB80> >'''

Geoaxes是特殊的axes对象,能按指定的坐标系统加载绘制不同形式的空间坐标数据。

加载数据:
下面是Geoaxes对象支持加载的一些数据:

(1)Natural Earth共享数据网站上的开放数据。

(2)shapely包定义的Geometries对象数据。

  • add_geometries(geoms, crs) 方法,加载指定crs的Geometries对象数据。
  • 另外,通过io模块中的shapereader函数可以读取 Esri 的 shapefile数据,然后转换成Geometries对象进行加载。

(3)wms(Web地图服务)和wmts(Web地图切片服务)数据。

  • add_wms()方法,加载wms(Web地图服务)数据, 参数wms设置要使用的 web 地图服务 URL 或 owslib WMS 实例,参数layers设置调用的图层名称。
  • add_wmts()方法,加载wmts(Web地图切片服务)数据,参数wmts设置服务的URL,参数layer_name设置调用的图层名称。

示例(1):在不同坐标系下绘制Natural Earth共享数据网站上的地图数据

代码及注释:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
fig = plt.figure(figsize=(8, 6))
crs = ccrs.PlateCarree()
ax = fig.add_subplot(3, 1, 1, projection=crs)
ax.stock_img()  # 加载地理坐标系统下的全球晕渲地形图
crs = ccrs.AlbersEqualArea(central_longitude=105.0, standard_parallels=(25.0, 45.0))
ax = fig.add_subplot(3, 1, 2, projection=crs)
ax.stock_img()  # 加载阿伯斯等积投影坐标系统下的全球晕渲地形图
ax = fig.add_subplot(3, 1, 3, projection=ccrs.PlateCarree())
ax.coastlines()  # 加载地理坐标系统下的全球海陆边界线地图
plt.show()

示例(2):利用shape矢量数据来加载地理坐标系下的中国国界图

代码及注释:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.shapereader as sr
fig = plt.figure()
crs = ccrs.PlateCarree()
ax = fig.add_subplot(1, 1, 1, projection=crs)
geom = sr.Reader("D:/tmp/shapedata/中国国界.shp").geometries()  # 读取shapefile数据,转换成Geometries对象进行加载
ax.add_geometries(geom, crs)  # 将Geometries对象数据加载到绘图区域
ax.set_extent((70, 140, 0, 60), crs)  # 设置指定坐标系下的地图显示范围
plt.show()

效果图:
在这里插入图片描述
示例(3):加载arcgisonline提供的网络地图服务数据

示例:把点数据叠置在不同坐标参照系统的背景地图上
( 在利用plot()绘制点图时,如果点数据和绘图区域的坐标系统不一致,可以定义关键字参数transform的值为数据的crs对象,即可将点数据转换成绘图区域坐标值 )

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
crs = ccrs.AlbersEqualArea(central_longitude=105.0, standard_parallels=(25.0, 45.0))
ax = plt.axes(projection=crs)
ax.coastlines(resolution='110m')
ax.stock_img()
x_list = [116.37, 121.53, 113.25]
y_list = [39.92, 31.26, 23.13]
city = ["beijing", "shanghai", "guangzhou"]
data_crs = ccrs.PlateCarree()
plt.plot(x_list, y_list, "o", color="r", markersize=6, transform=data_crs)  # 绘制点
for i in range(len(city)):
    plt.text(x_list[i], y_list[i], city[i], transform=data_crs, color="b")  # 添加点的标注
ax.set_extent((70, 140, 0, 60), ccrs.PlateCarree())
plt.show()

3.绘制网格线

Geoaxes对象的gridlines()方法用于绘制网格线,该方法返回一个Gridliner对象,通过对Gridliner对象属性设置,可以绘制不同形式的网格线。

网格线的一些相关属性:

  • xlines和ylines,x和y轴是否画线;
  • xlocator和ylocation,画线的位置;
  • xlabels_top、xlabels_bottom、xlabels_left、xlabels_right,标注的位置;
  • xformatter和yformatter,标注的格式。(这里 cartopy.mpl.gridliner定义了LONGITUDE_FORMATTER和LATITUDE_FORMATTER两个类,用于产生格式化的经纬度标注。)

示例:绘制中国区域的网格线及其标注

import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import cartopy.feature
import cartopy.crs as ccrs
from cartopy.mpl.gridliner import LATITUDE_FORMATTER, LONGITUDE_FORMATTER
ax = plt.axes(projection=ccrs.PlateCarree())
ax.coastlines()
ax.stock_img()
ax.set_extent((70, 140, 0, 60), ccrs.PlateCarree())
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=2, color='gray')
gl.xlocator = mticker.FixedLocator([70, 80, 90, 100, 110, 120, 130, 140])
gl.ylocator = mticker.FixedLocator([0, 10, 20, 30, 40, 50, 60])
gl.xformartter = LONGITUDE_FORMATTER
gl.yformartter = LATITUDE_FORMATTER
gl.xlabel_style = {'size': 12, 'color': 'gray'}
gl.ylabel_style = {'size': 12, 'color': 'gray'}
plt.show()

3、官网绘制示例

下面从官网:https://scitools.org.uk/cartopy/docs/latest/gallery/index.html上找了一些有趣的地图绘制例子。官网给出的示例,都是比较清晰健壮的代码编写出来的,感兴趣的朋友也可以自己分析研读一下,为自己制图培养一些技巧与灵感。😀
示例一:

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import matplotlib.textpath
import matplotlib.patches
from matplotlib.font_manager import FontProperties
import numpy as np
fig = plt.figure(figsize=[12, 6])
ax = fig.add_subplot(1, 1, 1, projection=ccrs.Robinson())
ax.coastlines()
ax.gridlines()
# generate a matplotlib path representing the word "cartopy"
fp = FontProperties(family='Bitstream Vera Sans', weight='bold')
logo_path = matplotlib.textpath.TextPath((-175, -35), 'cartopy',
                                         size=1, prop=fp)
# scale the letters up to sensible longitude and latitude sizes
logo_path._vertices *= np.array([80, 160])
# add a background image
im = ax.stock_img()
# clip the image according to the logo_path. mpl v1.2.0 does not support
# the transform API that cartopy makes use of, so we have to convert the
# projection into a transform manually
plate_carree_transform = ccrs.PlateCarree()._as_mpl_transform(ax)
im.set_clip_path(logo_path, transform=plate_carree_transform)
 # add the path as a patch, drawing black outlines around the text
patch = matplotlib.patches.PathPatch(logo_path,
                                      facecolor='none', edgecolor='black',
                                      transform=ccrs.PlateCarree())
ax.add_patch(patch)
plt.show()
import matplotlib.path as mpath
import matplotlib.pyplot as plt
import numpy as np
import cartopy.crs as ccrs
import cartopy.feature as cfeature
def main():
    fig = plt.figure(figsize=[10, 5])
    ax1 = fig.add_subplot(1, 2, 1, projection=ccrs.SouthPolarStereo())
    ax2 = fig.add_subplot(1, 2, 2, projection=ccrs.SouthPolarStereo(),
                          sharex=ax1, sharey=ax1)
    fig.subplots_adjust(bottom=0.05, top=0.95,
                        left=0.04, right=0.95, wspace=0.02)
    # Limit the map to -60 degrees latitude and below.
    ax1.set_extent([-180, 180, -90, -60], ccrs.PlateCarree())
    ax1.add_feature(cfeature.LAND)
    ax1.add_feature(cfeature.OCEAN)
    ax1.gridlines()
    ax2.gridlines()
    ax2.add_feature(cfeature.LAND)
    ax2.add_feature(cfeature.OCEAN)
    # Compute a circle in axes coordinates, which we can use as a boundary
    # for the map. We can pan/zoom as much as we like - the boundary will be
    # permanently circular.
    theta = np.linspace(0, 2*np.pi, 100)
    center, radius = [0.5, 0.5], 0.5
    verts = np.vstack([np.sin(theta), np.cos(theta)]).T
    circle = mpath.Path(verts * radius + center)
    ax2.set_boundary(circle, transform=ax2.transAxes)
    plt.show()
if __name__ == '__main__':
    main()
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import shapely.geometry as sgeom
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
def sample_data():
    Return a list of latitudes and a list of longitudes (lons, lats)
    for Hurricane Katrina (2005).
    The data was originally sourced from the HURDAT2 dataset from AOML/NOAA:
    https://www.aoml.noaa.gov/hrd/hurdat/newhurdat-all.html on 14th Dec 2012.
    lons = [-75.1, -75.7, -76.2, -76.5, -76.9, -77.7, -78.4, -79.0,
            -79.6, -80.1, -80.3, -81.3, -82.0, -82.6, -83.3, -84.0,
            -84.7, -85.3, -85.9, -86.7, -87.7, -88.6, -89.2, -89.6,
            -89.6, -89.6, -89.6, -89.6, -89.1, -88.6, -88.0, -87.0,
            -85.3, -82.9]
    lats = [23.1, 23.4, 23.8, 24.5, 25.4, 26.0, 26.1, 26.2, 26.2, 26.0,
            25.9, 25.4, 25.1, 24.9, 24.6, 24.4, 24.4, 24.5, 24.8, 25.2,
            25.7, 26.3, 27.2, 28.2, 29.3, 29.5, 30.2, 31.1, 32.6, 34.1,
            35.6, 37.0, 38.6, 40.1]
    return lons, lats
def main():
    fig = plt.figure()
    # to get the effect of having just the states without a map "background"
    # turn off the background patch and axes frame
    ax = fig.add_axes([0, 0, 1, 1], projection=ccrs.LambertConformal(),
                      frameon=False)
    ax.patch.set_visible(False)
    ax.set_extent([-125, -66.5, 20, 50], ccrs.Geodetic())
    shapename = 'admin_1_states_provinces_lakes'
    states_shp = shpreader.natural_earth(resolution='110m',
                                         category='cultural', name=shapename)
    lons, lats = sample_data()
    ax.set_title('US States which intersect the track of '
                 'Hurricane Katrina (2005)')
    # turn the lons and lats into a shapely LineString
    track = sgeom.LineString(zip(lons, lats))
    # buffer the linestring by two degrees (note: this is a non-physical
    # distance)
    track_buffer = track.buffer(2)
    def colorize_state(geometry):
        facecolor = (0.9375, 0.9375, 0.859375)
        if geometry.intersects(track):
            facecolor = 'red'
        elif geometry.intersects(track_buffer):
            facecolor = '#FF7E00'
        return {'facecolor': facecolor, 'edgecolor': 'black'}
    ax.add_geometries(
        shpreader.Reader(states_shp).geometries(),
        ccrs.PlateCarree(),
        styler=colorize_state)
    ax.add_geometries([track_buffer], ccrs.PlateCarree(),
                      facecolor='#C8A2C8', alpha=0.5)
    ax.add_geometries([track], ccrs.PlateCarree(),
                      facecolor='none', edgecolor='k')
    # make two proxy artists to add to a legend
    direct_hit = mpatches.Rectangle((0, 0), 1, 1, facecolor="red")
    within_2_deg = mpatches.Rectangle((0, 0), 1, 1, facecolor="#FF7E00")
    labels = ['State directly intersects\nwith track',
              'State is within \n2 degrees of track']
    ax.legend([direct_hit, within_2_deg], labels,
              loc='lower left', bbox_to_anchor=(0.025, -0.1), fancybox=True)
    plt.show()
if __name__ == '__main__':
    main()
import matplotlib.pyplot as plt
import numpy as np
import cartopy.crs as ccrs
import cartopy.feature as cfeature
def sample_data(shape=(20, 30)):
    Return ``(x, y, u, v, crs)`` of some vector data
    computed mathematically. The returned crs will be a rotated
    pole CRS, meaning that the vectors will be unevenly spaced in
    regular PlateCarree space.
    crs = ccrs.RotatedPole(pole_longitude=177.5, pole_latitude=37.5)
    x = np.linspace(311.9, 391.1, shape[1])
    y = np.linspace(-23.6, 24.8, shape[0])
    x2d, y2d = np.meshgrid(x, y)
    u = 10 * (2 * np.cos(2 * np.deg2rad(x2d) + 3 * np.deg2rad(y2d + 30)) ** 2)
    v = 20 * np.cos(6 * np.deg2rad(x2d))
    return x, y, u, v, crs
def main():
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1, projection=ccrs.Orthographic(-10, 45))
    ax.add_feature(cfeature.OCEAN, zorder=0)
    ax.add_feature(cfeature.LAND, zorder=0, edgecolor='black')
    ax.set_global()
    ax.gridlines()
    x, y, u, v, vector_crs = sample_data()
    ax.quiver(x, y, u, v, transform=vector_crs)
    plt.show()
if __name__ == '__main__':
    main()
                    🗺  🌏Cartopy地图绘图包——“专为地理空间数据处理而设计,以生成地图和其他地理空间数据分析。”,是在PROJ、pyshp、shapely、GEOS等Python包的基础上编写的,在安装时,需要同时安装相关的依赖包。🌎Cartopy包对Matplotlib包的功能进行了扩展,两者结合使用能绘制各种地图。详情介绍可访问官网:https://scitools.org.uk/cartopy/docs/latest/index.html🗺
常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 一、基础介绍
首先导入相关模块。
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
				
1、什么是cartopy cartopyCartopy 是一个开源免费的第三方 Python 扩展,由英国气象办公室的科学家们开发,支持 Python 2.7 和 Python 3,致力于使用最简单直观的方式生成地图,并提供对 matplotlib 友好的协作接口。该工具使用 LGPLv3 协议,代码托管在 Github 网站上。 2、为什么要使用cartopy 作为python2的殉葬品,B...
地图地图常用的python模块较为常用的是basemap和cartopy,其中basemap是基于python2开发的,最近自己使用python3比较多,所以学习了一下cartopy模块(支持python3),这里主要记录学习笔记,cartopy的安装与简单使用。 文章目录一、Cartopy介绍与安装1.Cartopy介绍2.Cartopy安装与实用二、实例展示参考资料 一、Cartopy介绍与安装 1.Cartopy介绍 Cartopy是一个用于地理空间数据处理的Python,用于生成地图和其他地理
常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 将地球三维球体投影到二维面上,减少失真。主要方式有默认投影(PlateCarree)、兰勃脱投影(Lambert)、墨卡托投影(Mercator)、极投影。 import cartopy.crs as ccrs import matplotlib.pyplot as plt #plt.axes是创建一个轴
下载并安装Cartopy Cartopy下载地址: linux平台直接去官网下载:http://scitools.org.uk/cartopy/download.html windows平台下的Cartopy下载地址: http://www.lfd.uci.edu/~gohlk...
好的,很高兴为您解答。在学习Cartopy制图的第二步中,我们将探索如何在地图上添加标记和注释。 首先,我们需要导入Cartopy和Matplotlib的相关库: import cartopy.crs as ccrs import matplotlib.pyplot as plt 接下来,我们将创建一个带有注释和标记的地图。这里我们以美国为例: # 创建一个以美国为中心的地图 ax = plt.axes(projection=ccrs.PlateCarree()) ax.set_extent([-130, -60, 20, 50], crs=ccrs.PlateCarree()) # 添加州边界线 states_provinces = cfeature.NaturalEarthFeature( category='cultural', name='admin_1_states_provinces_lines', scale='50m', facecolor='none') ax.add_feature(states_provinces, edgecolor='gray') # 添加湖泊和河流 lakes = cfeature.NaturalEarthFeature( category='physical', name='lakes', scale='50m', facecolor='none') ax.add_feature(lakes, edgecolor='blue') rivers = cfeature.NaturalEarthFeature( category='physical', name='rivers_lake_centerlines', scale='50m', facecolor='none') ax.add_feature(rivers, edgecolor='blue') # 添加城市标记 ax.plot(-75, 40, 'bo', markersize=7, transform=ccrs.PlateCarree()) ax.text(-75.5, 40.5, 'New York', transform=ccrs.PlateCarree()) # 添加注释 ax.text(-129, 22, 'USA', horizontalalignment='left', transform=ccrs.Geodetic()) ax.text(-100, 25, 'Great Lakes', horizontalalignment='center', transform=ccrs.PlateCarree()) ax.text(-98, 37, 'Mississippi River', horizontalalignment='center', transform=ccrs.PlateCarree()) plt.show() 这段代码会绘制一个以美国为中心的地图,同时添加州边界线、湖泊和河流的标记和注释。其中,城市标记是以蓝色圆点的形式添加的,注释则是以文本的形式添加的。 这就是在Cartopy制图中添加标记和注释的基本方法。希望对您有所帮助!