前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >地图1-图例式地图

地图1-图例式地图

作者头像
用户11172986
发布2025-03-06 23:27:05
发布2025-03-06 23:27:05
700
代码可运行
举报
文章被收录于专栏:气python风雨气python风雨
运行总次数:0
代码可运行

图例式地图

  图例式地图往往是论文中的第一张图片,用来展示研究区域的某种特征。一般有讲述研究地区的地貌图、展示数据站点分布的站点图、展示某些特定图注信息的地图,或者这些地图的叠加形式。而这些图片往往在文章的前部,画好这种介绍性图片,可以起到首先抓住眼球的作用。   接下来的几个章节,我们来介绍几种地理科学上常用的地图的绘制方法。希望帮助到大家。

什么是图例式地图

  图例式地图一般是图注信息丰富的图,一般表现在图例Legend比较丰富,例如下面这两张图片。

  图1即是典型的图例式地图,主要介绍研究区域的情况,没有涉及到太多具体的研究数据和结论。图2则是一张综合式的图例式地图,主图为地貌图,附图是介绍地质结构和海拔的图像。在气象上,我们多涉及到图1的样式,也兼有图2的样式。

duck-like理论在图例中的应用

  这是一个学习Python时的经典理论,一个东西看起来像鸭子,叫起来像鸭子,走路像鸭子,那他就是鸭子。那么我们在学习绘图的时候,亦可以使用这个理论。一个东西看起来像图例,那他就是图例。   引入这种理论的原因是matplotlib自带的legend命令绘制图例的时候不是非常方便,那么我们需要使用其他的技法来实现图例的绘制。

材料准备

  假定我们需要绘制湖北省宜昌市的研究区域图用作展示,我们决意画一个展示长江、清江等河流;区县名的研究区域图,以类似前文展示的图1中的方法。   我们就需要宜昌市地图文件、河流地图文件。在这些文件准备齐全后,我们开始绘图工作。正式绘图前,将需用功能模块和文件编入:

代码语言:javascript
代码运行次数:0
复制
import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import matplotlib.lines as ml
import matplotlib.patches as mpatches
import matplotlib.path as mpath
import cartopy.crs as ccrs
import cartopy.mpl.ticker as cmt
import cartopy.mpl.gridliner as cmg
import cartopy.mpl.patch as cmp 
import matplotlib.transforms as mt
from matplotlib.font_manager import FontProperties
font=FontProperties(fname=r'C:\Users\Administrator\AppData\Local\Microsoft\Windows\Fonts\3 得意黑 斜体.ttf')
#宜昌市行政区划文件
shp_file=r'G:\geo_shp\hubei_quansheng\hubei_quansheng.shp'
#河流文件
river1_file=r'G:\geo_shp\一三级四五级河流\一级.shp'
river3_file=r'G:\geo_shp\一三级四五级河流\三级.shp'
river4_file=r'G:\geo_shp\一三级四五级河流\四级.shp'
river5_file=r'G:\geo_shp\一三级四五级河流\五级.shp'
igdf=gpd.read_file(shp_file)
rgdf1=gpd.read_file(river1_file)
rgdf3=gpd.read_file(river3_file)
rgdf4=gpd.read_file(river4_file)
rgdf5=gpd.read_file(river5_file)

绘图

  首先,我们需要将地图主要地理信息添加到画布上

代码语言:javascript
代码运行次数:0
复制
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
fig=plt.figure(figsize=(5,5),dpi=400)
ax=fig.add_axes([0,0,1,1],projection=ccrs.PlateCarree())
ax.set_extent([110,113,29.8,31.7])
#添加宜昌区县边界
igdf.query('DNAME=="宜昌市"').plot(ax=ax,color='w',lw=0.4)
igdf.query('DNAME=="宜昌市"').boundary.plot(ax=ax,color='k',lw=0.4,alpha=0.5)
#添加宜昌主要河流边界
rgdf1.query('NAME=="长江"').plot(ax=ax,color='k',lw=4,alpha=0.5)
rgdf4.query('NAME=="清江"').plot(ax=ax,color='grey',lw=1.5)
rgdf5.query('NAME=="松滋河"').plot(ax=ax,color='grey',lw=1)
rgdf4.query('NAME=="沮漳河"').plot(ax=ax,color='grey',lw=1)
#这一步是生成宜昌市边界缓冲
ax.add_geometries([igdf.query('DNAME=="宜昌市"').unary_union.buffer(0.1)],
                  crs=ccrs.PlateCarree(),facecolor='grey',alpha=0.4,zorder=0)

  接下来,使用cartopy的gridlines命令添加经纬度标记:

代码语言:javascript
代码运行次数:0
复制
gl=ax.gridlines(draw_labels=True,linewidth=0.5,linestyle='--',color='grey',alpha=0.75)
gl.xlocator=mticker.FixedLocator(np.arange(110,112.5,0.5))
gl.ylocator=mticker.FixedLocator(np.arange(29.8,31.7,0.5))
gl.top_labels=True
gl.right_labels=True
gl.bottom_labels=True
gl.rotate_labels=None
gl.xformatter=cmg.LONGITUDE_FORMATTER
gl.yformatter=cmg.LATITUDE_FORMATTER
gl.x_inline=False
gl.y_inline=False
gl.xlabel_style={'size':10,'fontfamily':'Times New Roman'}
gl.ylabel_style={'size':10,'fontfamily':'Times New Roman'}

  为各河流添加名称(由于河流弯曲程度较大,实际上没有合适的自动化命令):

代码语言:javascript
代码运行次数:0
复制
ax.text(110.43,31.05,'长',fontsize=15,rotation=-15,alpha=0.75)
ax.text(112.1,30.33,'江',fontsize=15,rotation=15,alpha=0.75)
ax.text(111.45,31.35,'沮',fontsize=10,rotation=40,alpha=0.75)
ax.text(111.69,30.95,'漳',fontsize=10,alpha=0.75)
ax.text(112,30.6,'河',fontsize=10,alpha=0.75)
ax.text(110.25,30.45,'清',fontsize=10,rotation=10,alpha=0.75)
ax.text(110.95,30.45,'江',fontsize=10,alpha=0.75)
ax.text(111.78,30.16,'松',fontsize=10,rotation=20,alpha=0.75)
ax.text(111.9,30.1,'滋',fontsize=10,rotation=15,alpha=0.75)
ax.text(112.05,29.97,'河',fontsize=10,rotation=15,alpha=0.75)

  提取每个区县的中心,作为标记区县的坐标依据,根据shp文件中给出的信息来对每个行政区划进行标记:

代码语言:javascript
代码运行次数:0
复制
yichang=igdf.query('DNAME=="宜昌市"')
yichang['center']=yichang['geometry'].representative_point()
for i in range(yichang.shape[0]):
    ax.scatter(yichang.iloc[i]['center'].x,yichang.iloc[i]['center'].y,marker='H',c='gray',alpha=0.5,zorder=10)
    ax.text(yichang.iloc[i]['center'].x-0.05,
            yichang.iloc[i]['center'].y+0.04,
            yichang.iloc[i]['XNAME'],fontsize=6,fontproperties=font)

  新建一个ax,作为图例区域,并在图例上添加对应图注:

代码语言:javascript
代码运行次数:0
复制
inv=fig.transFigure.inverted()
pos=inv.transform(ax.transAxes.transform([(0.73,0.4)]))
ax_legend=fig.add_axes([pos[0][0],pos[0][1],0.25,0.42])
ax_legend.set(xticks=[],yticks=[])
ax_legend.set(xlim=[0,1],ylim=(0,2))
ax_legend.plot([0.1,0.55],[1.85,1.85],lw=10,c='grey',alpha=0.4)
ax_legend.text(0.65,1.82,'宜昌市界',fontsize=6)
ax_legend.plot([0.1,0.55],[1.55,1.55],lw=0.7,c='k',alpha=0.4)
ax_legend.text(0.65,1.55,'区县边界',fontsize=6)
ax_legend.scatter(0.35,1,marker='H',c='gray',alpha=0.5)
ax_legend.text(0.65,0.95,'区县名称',fontsize=6)
ax_legend.text(0.2,0.1,'绘制:云台书使',fontproperties=font)

  上面已经对主要图注进行了标记,我们再提取清江河流的最后一段作为河流的图像标志,为了能在图像上展示,我们对数据进行收缩(因为ax_legend设置了xlim和ylim):

代码语言:javascript
代码运行次数:0
复制
x=np.array(rgdf4.query('NAME=="清江"').iloc[-1]['geometry'].xy[0])-109
y=np.array(rgdf4.query('NAME=="清江"').iloc[-1]['geometry'].xy[1])-30+1
ax_legend.plot(x,y,color='grey')
ax_legend.text(0.65,1.2,'主要河流',fontsize=6)

  这样一个富图注地图就实现了。在添加图例的过程中,我们并没有直接使用legend命令,而是新建了一个小ax作为载具来承载图例。ax的绘图方法是比legend丰富的。另外这也是前面duck-like理论的实现,看起来是图例,那它就是图例。   在下一篇推文中,我们来介绍地貌填色地图和区划缩放地图的绘制方式。

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

本文分享自 气python风雨 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 图例式地图
    • 什么是图例式地图
    • duck-like理论在图例中的应用
    • 材料准备
    • 绘图
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档