首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用matplotlib cartopy绘制半球面地图(如北半球)

如何使用matplotlib cartopy绘制半球面地图(如北半球)
EN

Stack Overflow用户
提问于 2022-07-30 18:38:45
回答 1查看 126关注 0票数 1

如何用拼图绘制半球面(如北半球)的地图。

我正试着用卡通画出北半球的地图。但我不明白该如何定义地图的范围,这样才能绘制出这一感兴趣的区域。我想在0°纬度上切断这张地图。我希望有代码,可以轻松地使用ccrs.NearsidePerspective投影或ccrs.Orthographic投影定义glob的任何子集。

下面我留下了一个复制代码。

代码语言:javascript
复制
import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

# Creating fake data
x = np.linspace(-180, 180, 361)
y = np.linspace(-90, 90, 181)
lon, lat = np.meshgrid(x, y)
values = np.random.random(lon.shape)*20


fig = plt.figure(figsize=(15, 10))

proj = ccrs.NearsidePerspective(central_longitude=-45, central_latitude=21)

ax = fig.add_subplot(121, projection=proj)
ax.set_extent([-120, 40, 0, 60])

ax.pcolormesh(lon, lat, values, transform=ccrs.PlateCarree())

ax.coastlines(linewidth=2)
gl = ax.gridlines(draw_labels=True, linestyle='--')

代码生成以下图:

先谢谢你。罗布森

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-04 16:32:37

要只绘制地图投影的上半球部分,需要使用该部分的多边形作为投影边界。

该多边形是作为matplotlib路径对象创建的。它的顶点坐标是我的代码中的数据坐标,因此,当应用于最终的绘图时,不需要进行转换。

这是一个完整的代码:-

代码语言:javascript
复制
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import matplotlib.path as mpath
import numpy as np
from geographiclib.geodesic import Geodesic

fig = plt.figure(figsize=[12, 12])
proj = ccrs.NearsidePerspective(central_longitude=-45, central_latitude=21, satellite_height=35785831)
ax = plt.subplot(projection=proj)

# The value of r is obtained by previous run of this code ...
#  with the line .. #print(ax.get_xlim()) uncommented
r = 5476336.098
ax.set_xlim(-r, r)
ax.set_ylim(-r, r)

ax.stock_img()
ax.coastlines(lw=1, color="darkblue")

# Find the locations of points along the equatorial arc
# start location
lon_fr, lat_fr = 30, 0
# end location
lon_to, lat_to = -120, 0

# This gets geodesic between the two points, WGS84 ellipsoid is used
geodl = Geodesic.WGS84.InverseLine(lat_fr, lon_fr, lat_to, lon_to)

lonlist, latlist = [], []
num_points = 32  #for series of points on geodesic/equator
for ea in np.linspace(0, geodl.s13, num_points):
    g = geodl.Position(ea, Geodesic.STANDARD | Geodesic.LONG_UNROLL)
    #print("{:.0f} {:.5f} {:.5f} {:.5f}".format(g['s12'], g['lat2'], g['lon2'], g['azi2']))
    lon2, lat2 = g['lon2'], g['lat2']
    lonlist.append( g['lon2'] )
    latlist.append( g['lat2'] )

# Get data-coords from (lonlist, latlist)
# .. as points along equatorial arc
dataxy = proj.transform_points(ccrs.PlateCarree(), np.array(lonlist), np.array(latlist))

# (Uncomment to) Plot equator line
#ax.plot(dataxy[:, 0:1], dataxy[:, 1:2], "go-", linewidth=2, markersize=5, zorder=10)

# Top semi-circle arc for map extent
theta = np.linspace(-0.5*np.pi, 0.5*np.pi, 64)
center, radius = [0, 0], r
verts = np.vstack([np.sin(theta), np.cos(theta)]).T

# Combine vertices of the semi-circle and equatorial arcs
# These points are in data coordinates, ready to plot on the axes.
verts = np.vstack([verts*r, dataxy[:, 0:2]])

polygon = mpath.Path(verts + center)
ax.set_boundary(polygon) #This masks-out unwanted part of the plot

gl = ax.gridlines(draw_labels=True, xlocs=range(-150,180,30), ylocs=range(0, 90, 15), 
                  y_inline=True, linestyle='--', lw= 5, color= "w", )

# Get limits, the values are the radius of the circular map extent
# The values is then used as r = 5476336.09797 on top of the code
#print(ax.get_xlim())
#print(ax.get_ylim())

plt.show()

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73178207

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档