ZhaJiMan / frykit

A simple toolbox for drawing china map in Python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

frykit

一个配合 Matplotlib 和 Cartopy 使用的工具箱,主要由 shpplot 模块组成。

shp 模块的功能是:

  • 读取**行政区划数据
  • 创建多边形掩膜(mask)
  • 多边形在不同投影坐标系之间的变换

plot 模块的功能包括:

  • 读取**行政区划数据
  • 向地图添加**国界、省界和市界
  • 利用国界和省界对填色图做裁剪(白化)
  • 标注省名和市名
  • 设置地图刻度
  • 添加风矢量图的图例
  • 添加指北针
  • 添加地图比例尺
  • 制作离散色表

暂无文档,但是每个函数都有详细的 docstring,可以在 Python 命令行中通过 help 函数查看,或者在 IDE 中查看。

这个包只是作者自用的小工具集,函数编写粗糙,可能存在不少 bug,还请多多交流指正。类似的更完备的包还请移步 gmaEOmaps

安装

pip install frykit

frykit>=0.3.0 的依赖为:

python>=3.9.0
cartopy>=0.20.0
pandas>=1.2.0

更新记录

CHANGELOG.md

示例

读取**行政区划

import frykit.shp as fshp

# 读取国界.
border = fshp.get_cn_border()

# 读取省界.
provinces = fshp.get_cn_province()
anhui = fshp.get_cn_province(name='安徽省')

# 读取市界.
cities = fshp.get_cn_city()
hefei = fshp.get_cn_city(name='合肥市')
cities_of_anhui = fshp.get_cn_city(province='安徽省')

返回结果是 Shapely 的多边形对象,可以进行交并等几何运算。

行政区划源数据来自 高德地图行政区域查询接口,含国界、省界和市界三套数据,已从 GCJ-02 坐标系处理到了 WGS84 坐标系上。文件都在 frykit.DATA_DIRPATH 指向的目录里。制作方法见 amap-shp

绘制**国界、省界和市界

# 绘制国界.
fplt.add_cn_border(ax)

# 绘制九段线
fplt.add_nine_line(ax)

# 绘制省界.
fplt.add_cn_province(ax)
fplt.add_cn_province(ax, name=['安徽省', '江苏省'])

# 绘制市界
fplt.add_cn_city(ax)
fplt.add_cn_city(ax, name=['石家庄市', '保定市'])
fplt.add_cn_city(ax, province='河南省')

ax 可以是 AxesGeoAxes

标注省名和市名

fplt.label_cn_province(ax)
fplt.label_cn_city(ax, fontsize='xx-small')

默认采用 Normal 字重的思源黑体。

绘制任意多边形

import shapely.geometry as sgeom

# 绘制一个多边形.
polygon = sgeom.polygon(...)
fplt.add_polygon(ax, polygon)

# 绘制多个多边形并填色.
pc = fplt.add_polygons(ax, polygons, array=data, cmap=cmap, norm=norm)
cbar = fig.colorbar(pc, ax=ax)

Cartopy 的 GeoAxes.add_geometries 会自动去除不在 GeoAxes 显示范围内的 polygons,破坏 polygonsarray 的一一对应关系,打乱填色的结果。工具箱中的 add_polygons 函数不会进行这一操作,能够产生正确的填色结果。

裁剪填色图

cf = ax.contourf(lon, lat, data, transform=data_crs)

# 用国界或省界裁剪.
fplt.clip_by_cn_border(cf)
fplt.clip_by_cn_province(cf, '河北省')

被裁剪的对象还可以是 contourclabelpcolormeshquiver 等方法的返回值。

当用于裁剪的多边形超出 GeoAxes 的显示范围时,直接用 Artist.set_clip_path 做裁剪会发生填色图出界的现象(cartopy/issues/2052)。工具箱内的 clip_by_xxx 系列函数对此进行了处理。

加速绘制和裁剪

绘制多边形和裁剪填色图过程中需要对多边形进行坐标变换,工具箱默认进行速度更快,但结果不够严格的变换方法。快速和严格两种变换方法间的切换为:

enable_fast_transform()
disable_fast_transform()

add_cn_xxx 系列函数在多次调用时会通过缓存节省读取国界和省界数据的时间开销。如果能维持对多边形对象的引用,add_polygonadd_polygonsclip_by_xxx 系列函数在多次调用时会通过缓存节省多边形坐标变换的时间开销。

添加指北针和比例尺

fplt.add_compass(ax1, 0.95, 0.8, size=15, style='star')
map_scale = fplt.add_map_scale(ax1, 0.36, 0.8, length=1000)
map_scale.set_xticks([0, 500, 1000])

指北针会自动指向所在位置处的北向,也可以通过 angle 参数手动指定角度。

比例尺的长度通过 Axes 中心处单位长度和实际距离的比值计算得到。比例尺本身由一个压扁了的 Axes 模拟,所以可通过 set_xticks 等方法修改样式。

定位南海小地图

sub_ax = fig.add_subplot(projection=map_crs)
sub_ax.set_extent([105, 120, 2, 25], crs=data_crs)
fplt.move_axes_to_corner(sub_ax, ax)

需要先确定主图和子图的显示范围,再利用 move_axes_to_corner 函数将子图缩小并定位到主图的角落。

添加风矢量图例

fplt.add_quiver_legend(Q, U=10, width=0.15, height=0.12)

Axes 的角落添加一个白色矩形背景的风矢量图例。可以通过 rect_kwargs 字典控制矩形的样式,通过 key_kwargs 字典控制 quiverkey 的样式。

添加经纬度方框

fplt.add_box(ax, [lon0, lon1, lat0, lat1], transform=ccrs.PlateCarree())

axGeoAxes 时会对方框上的点插值,以保证方框在 ax 的坐标系里足够平滑。

GMT 风格边框

fplt.gmt_style_frame(ax, width=5)

使用类似 GMT 黑白相间格子的边框。目前仅支持 Axes 和矩形投影的 GeoAxes

离散 colorbar

# 一个颜色对应一个刻度的定性colorbar.
colors = [
    'orangered', 'orange', 'yellow',
    'limegreen', 'royalblue', 'darkviolet'
]
cmap, norm, ticks = fplt.make_qualitative_cmap(colors)
cbar = fplt.plot_colormap(cmap, norm)
cbar.set_ticks(ticks)
cbar.set_ticklabels(colors)

# 保证零值区间对应白色的离散colorbar.
import cmaps
boundaries = [-10, -5, -2, -1, 1, 2, 5, 10, 20, 50, 100]
norm = fplt.CenteredBoundaryNorm(boundaries)
cbar = fplt.plot_colormap(cmaps.BlueWhiteOrangeRed, norm)
cbar.set_ticks(boundaries)

colorbar

详细介绍

工具箱的原理和使用场景可见下面几篇博文:

示例效果

cd 到包的 example 目录里可以执行示例脚本:

axes

fill

quiver

contourf

nerv_style

About

A simple toolbox for drawing china map in Python

License:BSD 3-Clause "New" or "Revised" License


Languages

Language:Python 98.7%Language:Jupyter Notebook 1.3%