首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >cnmaps,你值得拥有!

cnmaps,你值得拥有!

作者头像
自学气象人
发布2023-06-21 16:04:52
发布2023-06-21 16:04:52
1.6K0
举报
文章被收录于专栏:自学气象人自学气象人

cnmaps经过很多小伙伴的反馈和协作开发,目前更新了一个小版本到1.1。增加了一些新的功能,同时做了一些优化,下面我们快速看一下都有哪些变化。

可以使用conda安装了

cnmaps 现在已经通过 conda-forge 发布,相比于 pip 来说,安装更为简单,只需要执行 conda install -c conda-forge cnmaps==1.1.0 即可, cartopy 等依赖会自动安装,但建议Python解释器在3.8及以上版本。

可以对散点和风矢做裁剪了

根据气象备忘录的反馈,增加了对风矢量图的裁剪功能。

代码语言:javascript
复制
import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from cnmaps import get_adm_maps, clip_quiver_by_map, clip_contours_by_map, draw_map
from cnmaps.sample import load_wind

lons, lats, u, v = load_wind()

fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())
map_polygon = get_adm_maps(country='中华人民共和国', record='first', only_polygon=True)

spd = (u ** 2 + v ** 2) ** 0.5

qv = ax.quiver(lons, lats, u, v,transform=ccrs.PlateCarree(), zorder=2)
cs = ax.contourf(lons, lats, spd, cmap=plt.cm.RdYlBu_r,
                levels=np.linspace(spd.min(), spd.max(), 50),
                transform=ccrs.PlateCarree(), zorder=1)

clip_contours_by_map(cs, map_polygon)
clip_quiver_by_map(qv, map_polygon)

draw_map(map_polygon, color='k', linewidth=1)

plt.show()

另外,也增加了裁剪散点图的功能。

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

from cnmaps import get_adm_maps, clip_scatter_by_map, draw_map
from cnmaps.sample import load_wind

lons, lats, u, v = load_wind()
spd = (u ** 2 + v ** 2) ** 0.5

data = list(zip(lons.flatten(), lats.flatten(), spd.flatten()))

x = [s[0] for s in data]
y = [s[1] for s in data]
z = [s[2] for s in data]

map_polygon = get_adm_maps(record='first', only_polygon=True)

fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())
scatter = ax.scatter(x, y, s=np.array(z)*10, c=z,
                     cmap=plt.cm.RdYlBu_r, transform=ccrs.PlateCarree())
clip_scatter_by_map(scatter, map_polygon)
draw_map(map_polygon, linewidth=1)
ax.set_extent(map_polygon.get_extent(buffer=1))

plt.show()

可以做栅格掩膜了

原本自己尝试实现过一套矢量地图做栅格掩膜的方案,但是效率很低。在炸鸡人的帮助下,使用他的递归方案大幅提高了效率,使掩膜方法的可用性大幅提高。炸鸡人介绍该方法的博客:https://zhajiman.github.io/post/cartopy_polygon_to_mask/,气象备忘录对该方法的介绍:Python 利用多边形生成掩膜数组

下面是cnmaps生成一套掩膜矩阵的例子。

代码语言:javascript
复制
import numpy as np
from cnmaps import get_adm_maps
import matplotlib.pyplot as plt

lon = np.linspace(60, 150, 1000)
lat = np.linspace(0, 60, 1000)
lons, lats = np.meshgrid(lon, lat)

china = get_adm_maps(level="国", record="first", only_polygon=True, wgs84=True)
china_maskout_array = china.make_mask_array(lons, lats)

plt.imshow(china_maskout_array, cmap='binary', origin='lower')

我们也可以直接对数据进行掩膜操作。

代码语言:javascript
复制
import numpy as np
from cnmaps import get_adm_maps
import matplotlib.pyplot as plt

lon = np.linspace(60, 150, 1000)
lat = np.linspace(0, 60, 1000)

lons, lats = np.meshgrid(lon, lat)
data = np.random.random(lons.shape)

china = get_adm_maps(level="国", record= "first", only_polygon=True, wgs84=True)

maskout_data = china.maskout(lons, lats, data)

plt.figure(figsize=(20,8))

plt.subplot(121)
plt.pcolormesh(lons, lats, data)
plt.title("no maskout")

plt.subplot(122)
plt.pcolormesh(lons, lats, maskout_data)
plt.title("maskout")
plt.show()

可以导出矢量文件了

cnmaps 支持将查询到的矢量边界输出为 GeoJSON 或 ESRI Shapefile 文件了。

代码语言:javascript
复制
from cnmaps import get_adm_maps

china = get_adm_maps(level="国", record= "first", only_polygon=True)

china.to_file('./china.geojson')  # 默认为 geojson 格式文件
china.to_file('./china.shp', engine='ESRI Shapefile')  # 也可以指定 shapefile 格式文件

可以按WGS84坐标导入了

由于原始数据来自于高德API,地图坐标系为火星坐标系(GCJ02),因此在新版本的 cnmaps 中,我们增加了对坐标转换的“开关”,在get_adm_maps函数中引入了 wgs84 的参数,例如:

代码语言:javascript
复制
from cnmaps import get_adm_maps

china = get_adm_maps(level="国", record= "first", only_polygon=True, wgs84=True)

当我们传入wgs84=True 时,加载的地图会自动从火星坐标系转为WGS84坐标系,若为 False 则按火星坐标系加载,默认为wgs84=True

裁剪和绘图的效率提高了

新版本的 cnmaps 对裁剪和绘图的程序进行了性能优化(虽然可能还有很大的优化空间)

今天特意在我的Intel Mac上测试了一下以下面这段代码:

代码语言:javascript
复制
import time

import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cnmaps import get_adm_maps, clip_contours_by_map, draw_map
from cnmaps.sample import load_dem

lons, lats, data = load_dem()

t0 = time.time()
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())
map_polygon = get_adm_maps(country="中华人民共和国", record="first", only_polygon=True)

cs = ax.contourf(
    lons,
    lats,
    data,
    cmap=plt.cm.terrain,
    levels=np.linspace(-2800, data.max(), 10),
    transform=ccrs.PlateCarree(),
)

clip_contours_by_map(cs, map_polygon)
draw_map(map_polygon, color="k", linewidth=1)

plt.savefig('./china.png')

t1 = time.time()

time_delta = t1 - t0

print("time_delta", time_delta)

cnmaps==1.0.1 下运行耗时达到了惊人的 902 秒(15分钟,emmmmmmm),而在 cnmaps==1.1.0 下运行耗时为 52 秒(虽然可能还是有点慢,但没有15分钟那么离谱),当然后续还会继续优化。

再次感谢炸鸡人在新版本 cnmaps 性能优化上的贡献。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 自学气象人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 可以使用conda安装了
  • 可以对散点和风矢做裁剪了
  • 可以做栅格掩膜了
  • 可以导出矢量文件了
  • 可以按WGS84坐标导入了
  • 裁剪和绘图的效率提高了
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档