cartopy绘制地图第七天(python绘制地形图和比例尺)

本文使用python和cartopy绘制地形图,同时绘制了比例尺。

首先,上图是恭敬的。一些图例符号是错误的。请不要介意。随便表达

一、下载地形图

想要绘制地形图的朋友,第一步就是下载地形图文件。该网站是自然地球,网站是:https://www.naturalearthdata.com/downloads/

只有1:10和1:50的浮雕图,也就是第三个选项“格子”(别问我为什么是中国人,问我告诉你我是浏览器翻译的。)

只需单击并找到您需要下载的内容。反正我电脑里1:10最大的地图画不出来。错误报告显示地图太大。其他一切都很好。根据实际情况下载即可。

下载后是一个压缩包。解压得到XXXXXX TIF文件就好了。可以在代码目录中使用。

二、绘制地形图

事实上,这并不难。我只是告诉你cartopy可以画地形图

#地图周围的经纬度

西 u003d 110

东 u003d 125

南 u003d 20

北 u003d 30

#解决中文乱码问题

plt.rcParams['font.sans-serif'] u003d ['SimHei']

#画布设置、投影设置

fig u003d plt.figure(figsizeu003d(16,9.6))

ax u003d fig.add_subplot(111,projection u003d ccrs.PlateCarree())

#边界设置

img_extent u003d [西、东、南、北]

ax.set_extent(img_extent,crs u003d ccrs.PlateCarree())

#浮雕地图导入

fname u003d 'HYP_LR_SR_OB_DR.tif'

ax.imshow(plt.imread(fname), originu003d'upper', transformu003dccrs.PlateCarree(),extentu003d[-180, 180, -90, 90])

有些朋友在这里还可以。

三、地图绘画之美

经纬网格设置

#设置经纬度网格和标签,将透明度改为1,就会出现网格alphau003d1

gl u003d ax.gridlines(crsu003dccrs.PlateCarree(), draw_labelsu003dTrue, linewidthu003d1, coloru003d'k', alphau003d1,linestyleu003d'--')#轴设置

gl.xformatter u003d LONGITUDE_FORMATTER ##坐标刻度转换为经纬度样式

gl.yformatter u003d LATITUDE_FORMATTER

#设置经度和纬度的显示,比如经度70到135,间隔5

gl.xlocator u003d mticker.FixedLocator(np.arange(70,135,5))

gl.ylocator u003d mticker.FixedLocator(np.arange(15,55,5))

绘制比例尺和黑白边框

def draw\the\scale(y,x,text,length u003d 1.5,lw u003d 5):

#绘制比例函数

y代表比例尺的纬度

x代表刻度开始处的经度

text 表示比例尺的最后一个比例值

#length 表示比例尺在经度上的长度

lw 表示比例尺的宽度

step u003d length/5#计算步长,绘制五个网格

#画五条黑白线

plt.hlines(yu003dy,xminu003dx,xmaxu003dx + step,colorsu003d"black", lsu003d"-", lwu003dlw)

plt.hlines(yu003dy,xminu003dx + step,xmaxu003dx + step*2,colorsu003d"white", lsu003d"-", lwu003dlw)

plt.hlines(yu003dy,xminu003dx + step*2,xmaxu003dx + step*3,colorsu003d"black", lsu003d"-", lwu003dlw)

plt.hlines(yu003dy,xminu003dx + step*3,xmaxu003dx + step*4,colorsu003d"white", lsu003d"-", lwu003dlw)

plt.hlines(yu003dy,xminu003dx + step*4,xmaxu003dx + step*5,colorsu003d"black", lsu003d"-", lwu003dlw)

#画两个长鳞片

plt.vlines(x u003d x, ymin u003d y - (lw/100) *3, ymax u003d y + lw/100, colorsu003d"black", lsu003d"-", lwu003d1)

plt.vlines(x u003d x + 长度, ymin u003d y - (lw/100) *3, ymax u003d y + lw/100, colorsu003d"black", lsu003d"-", lwu003d1)

#绘制四段

plt.vlines(x u003d x + step, ymin u003d y - (lw/100) *2, ymax u003d y + lw/100, colorsu003d"black", lsu003d"-", lwu003d1)

plt.vlines(x u003d x + step*2, ymin u003d y - (lw/100) *2, ymax u003d y + lw/100, colorsu003d"black", lsu003d"-", lwu003d1 )

plt.vlines(x u003d x + step*3, ymin u003d y - (lw/100) *2, ymax u003d y + lw/100, colorsu003d"black", lsu003d"-", lwu003d1 )

plt.vlines(x u003d x + step*4, ymin u003d y - (lw/100) *2, ymax u003d y + lw/100, colorsu003d"black", lsu003d"-", lwu003d1 )

#写作,0500 公里

plt.text(x,y - (lw/100) *7,'0',horizontalalignment u003d 'center')

plt.text(x + length,y - (lw/100) *7,text,horizontalalignment u003d 'center')

plt.text(x + length/2,y + (lw/100)*2,'km',horizontalalignment u003d 'center')

def drowscale(范围,scale_y,scale_x,scale_text,step u003d 5,lw u003d 10,scale_length u003d 1.5,scale_lw u003d 5):

绘制带有黑白边框和比例尺的地图

Ext:表示[west, east, south, north]周围的经纬度

scale\y,scale_x,scale\text:表示比例尺的位置、纬度、经度和比例值

Step:代表步长,一个格子代表几个经纬度

lw:代表边框的宽度

#scale_length:表示比例尺的长度(以经度为单位,例如1.5经度)

scale_lw:表示比例尺的宽度

for y in [extent[2],extent[3]] :#绘制上下边框

xmin u003d 范围[0]

而 (xmin < 范围[1]):

plt.hlines(yu003dy,xminu003dxmin,xmaxu003dxmin+step,colorsu003d"white", lsu003d"-", lwu003dlw)

xmin u003d xmin+步*2

xmin u003d 范围[0]+步长

而 (xmin < 范围[1]):

plt.hlines(yu003dy,xminu003dxmin,xmaxu003dxmin+step,colorsu003d"black", lsu003d"-", lwu003dlw)

xmin u003d xmin+步*2

for x in [extent[0],extent[1]] :#左右画

ymin u003d 范围[2]

而(ymin < 范围[3]):

plt.vlines(x u003d x, ymin u003d ymin, ymax u003d ymin+step, colorsu003d"black", lsu003d"-", lwu003dlw)

ymin u003d ymin+步*2

ymin u003d 范围[2]+步长

而(ymin < 范围[3]):

plt.vlines(x u003d x, ymin u003d ymin, ymax u003d ymin+step, colorsu003d"white", lsu003d"-", lwu003dlw)

ymin u003d ymin+步*2

drow_the_scale(scale_y,scale_x,scale_text)#绘制比例

这里写了两个函数,每个函数一个。其实就是在地图周围画黑白线,然后在画面中的某个位置画黑白线,形成一个比例尺。可以说是有些巧妙,也很不规范。默认情况下,1 度代表 111 公里。

主要原因是作者找不到cartopy绘图比例的功能。底图可以,但我不想使用它。如果有朋友知道,请留言告诉我。谢谢你。

绘制散点信息

随便画一些散点信息供朋友们使用。一共五个函数批量绘制散点。只需给出经度和纬度的列表。我随便在上面标了点。

def drowpentagram(ax,points,c u003d 'red',su003d300):

#绘制五个尖角星轴,points,c color,s size

对于点中点:

ax.scatter(point[0], point[1], marker u003d '*',c u003d c,su003ds,transformu003dccrs.PlateCarree())

plt.text(point[0],point[1]+0.3,point[2],horizontalalignment u003d 'center')

def drowcircle(ax,points,edgecolors u003d 'red',linewidths u003d 2,su003d300):

#Circle ax,points required, edgecolors color, s size, linewidths line width

对于点中点:

ax.scatter(point[0], point[1], marker u003d 'o',edgecolors u003d edgecolors,c u003d 'none',linewidths u003d linewidths,su003ds,transformu003dccrs.PlateCarree() )

def drowfork(ax,points,c u003d 'blue',linewidths u003d 2,su003d300):

#画十字轴,点,c颜色,s大小,线宽,线宽

对于点中点:

ax.scatter(point[0], point[1], marker u003d 'x',c u003d c,linewidths u003d linewidths,su003ds,transformu003dccrs.PlateCarree())

def drowbox(ax,points,edgecolors u003d 'blue',linewidths u003d 2,su003d300):

#绘制正方形 ax,points, required band, edgecolors color, s size, linewidths 线宽

对于点中点:

ax.scatter(point[0], point[1], marker u003d 's',edgecolors u003d edgecolors,c u003d 'none',linewidths u003d linewidths,su003ds,transformu003dccrs.PlateCarree() )

def drowtriangle(ax,points,edgecolors u003d 'blue',linewidths u003d 2,su003d300):

#绘制三角形 ax,points, required band, edgecolors color, s size, linewidths 线宽

对于点中点:

ax.scatter(point[0], point[1], marker u003d '^',edgecolors u003d edgecolors,c u003d 'none',linewidths u003d linewidths,su003ds,transformu003dccrs.PlateCarree() )

绘制图例

给出一个legend函数,封装

def drowlegend(ax,x,y,text,step u003d 0.5):

#绘制图例

x是图例左上角的经度;

y是图例左上角的纬度;

text 是文字描述;

step 是间距

drowcircle(ax,((x,y),))#画一个红色圆圈

plt.text(x+step*1.5,y ,text[0],horizontalalignment u003d 'center')

drowcircle(ax,((x,y - step),),edgecolors u003d 'green')#画一个绿色圆圈

plt.text(x+step*1.5,y- step,text[1],horizontalalignment u003d 'center')

drowfork(ax,((x,y - step*2),))#画一个叉子

plt.text(x+step*1.5,y- step*2,text[2],horizontalalignment u003d 'center')

drowbox(ax,((x,y - step*3),))#画正方形

plt.text(x+step*1.5,y- step*3,text[3],horizontalalignment u003d 'center')

drowtriangle(ax,((x,y - step*4),))#画三角形

plt.text(x+step*1.5,y- step*4,text[4],horizontalalignment u003d 'center')

! zoz100037](https://programming.vip/images/doc/7c5b7aba17a450d41b9cab0d40721af0.jpg)

四、所有代码

导入 matplotlib.pyplot 作为 plt

导入 cartopy.crs 作为 ccrs

将 numpy 导入为 np

从 cartopy.mpl.gridliner 导入 LATITUDE_FORMATTER、LONGITUDE_FORMATTER

导入 matplotlib.ticker 作为 mticker

def drowpentagram(ax,points,c u003d 'red',su003d300):

#绘制五个尖角星轴,points,c color,s size

对于点中点:

ax.scatter(point[0], point[1], marker u003d '*',c u003d c,su003ds,transformu003dccrs.PlateCarree())

plt.text(point[0],point[1]+0.3,point[2],horizontalalignment u003d 'center')

def drowcircle(ax,points,edgecolors u003d 'red',linewidths u003d 2,su003d300):

#Circle ax,points required, edgecolors color, s size, linewidths line width

对于点中点:

ax.scatter(point[0], point[1], marker u003d 'o',edgecolors u003d edgecolors,c u003d 'none',linewidths u003d linewidths,su003ds,transformu003dccrs.PlateCarree() )

def drowfork(ax,points,c u003d 'blue',linewidths u003d 2,su003d300):

#画十字轴,点,c颜色,s大小,线宽,线宽

对于点中点:

ax.scatter(point[0], point[1], marker u003d 'x',c u003d c,linewidths u003d linewidths,su003ds,transformu003dccrs.PlateCarree())

def drowbox(ax,points,edgecolors u003d 'blue',linewidths u003d 2,su003d300):

#绘制正方形 ax,points, required band, edgecolors color, s size, linewidths 线宽

对于点中点:

ax.scatter(point[0], point[1], marker u003d 's',edgecolors u003d edgecolors,c u003d 'none',linewidths u003d linewidths,su003ds,transformu003dccrs.PlateCarree() )

def drowtriangle(ax,points,edgecolors u003d 'blue',linewidths u003d 2,su003d300):

#绘制三角形 ax,points, required band, edgecolors color, s size, linewidths 线宽

对于点中点:

ax.scatter(point[0], point[1], marker u003d '^',edgecolors u003d edgecolors,c u003d 'none',linewidths u003d linewidths,su003ds,transformu003dccrs.PlateCarree() )

def draw\the\scale(y,x,text,length u003d 1.5,lw u003d 5):

#绘制比例函数

y代表比例尺的纬度

x代表刻度开始处的经度

text 表示比例尺的最后一个比例值

#length 表示比例尺在经度上的长度

lw 表示比例尺的宽度

step u003d length/5#计算步长,绘制五个网格

#画五条黑白线

plt.hlines(yu003dy,xminu003dx,xmaxu003dx + step,colorsu003d"black", lsu003d"-", lwu003dlw)

plt.hlines(yu003dy,xminu003dx + step,xmaxu003dx + step*2,colorsu003d"white", lsu003d"-", lwu003dlw)

plt.hlines(yu003dy,xminu003dx + step*2,xmaxu003dx + step*3,colorsu003d"black", lsu003d"-", lwu003dlw)

plt.hlines(yu003dy,xminu003dx + step*3,xmaxu003dx + step*4,colorsu003d"white", lsu003d"-", lwu003dlw)

plt.hlines(yu003dy,xminu003dx + step*4,xmaxu003dx + step*5,colorsu003d"black", lsu003d"-", lwu003dlw)

#画两个长鳞片

plt.vlines(x u003d x, ymin u003d y - (lw/100) *3, ymax u003d y + lw/100, colorsu003d"black", lsu003d"-", lwu003d1)

plt.vlines(x u003d x + 长度, ymin u003d y - (lw/100) *3, ymax u003d y + lw/100, colorsu003d"black", lsu003d"-", lwu003d1)

#绘制四段

plt.vlines(x u003d x + step, ymin u003d y - (lw/100) *2, ymax u003d y + lw/100, colorsu003d"black", lsu003d"-", lwu003d1)

plt.vlines(x u003d x + step*2, ymin u003d y - (lw/100) *2, ymax u003d y + lw/100, colorsu003d"black", lsu003d"-", lwu003d1 )

plt.vlines(x u003d x + step*3, ymin u003d y - (lw/100) *2, ymax u003d y + lw/100, colorsu003d"black", lsu003d"-", lwu003d1 )

plt.vlines(x u003d x + step*4, ymin u003d y - (lw/100) *2, ymax u003d y + lw/100, colorsu003d"black", lsu003d"-", lwu003d1 )

#写作,0500 公里

plt.text(x,y - (lw/100) *7,'0',horizontalalignment u003d 'center')

plt.text(x + length,y - (lw/100) *7,text,horizontalalignment u003d 'center')

plt.text(x + length/2,y + (lw/100)*2,'km',horizontalalignment u003d 'center')

def drowscale(范围,scale_y,scale_x,scale_text,step u003d 5,lw u003d 10,scale_length u003d 1.5,scale_lw u003d 5):

绘制带有黑白边框和比例尺的地图

Ext:表示[west, east, south, north]周围的经纬度

scale\y,scale_x,scale\text:表示比例尺的位置、纬度、经度和比例值

Step:代表步长,一个格子代表几个经纬度

lw:代表边框的宽度

#scale_length:表示比例尺的长度(以经度为单位,例如1.5经度)

scale_lw:表示比例尺的宽度

for y in [extent[2],extent[3]] :#绘制上下边框

xmin u003d 范围[0]

而 (xmin < 范围[1]):

plt.hlines(yu003dy,xminu003dxmin,xmaxu003dxmin+step,colorsu003d"white", lsu003d"-", lwu003dlw)

xmin u003d xmin+步*2

xmin u003d 范围[0]+步长

而 (xmin < 范围[1]):

plt.hlines(yu003dy,xminu003dxmin,xmaxu003dxmin+step,colorsu003d"black", lsu003d"-", lwu003dlw)

xmin u003d xmin+步*2

for x in [extent[0],extent[1]] :#左右画

ymin u003d 范围[2]

而(ymin < 范围[3]):

plt.vlines(x u003d x, ymin u003d ymin, ymax u003d ymin+step, colorsu003d"black", lsu003d"-", lwu003dlw)

ymin u003d ymin+步*2

ymin u003d 范围[2]+步长

而(ymin < 范围[3]):

plt.vlines(x u003d x, ymin u003d ymin, ymax u003d ymin+step, colorsu003d"white", lsu003d"-", lwu003dlw)

ymin u003d ymin+步*2

drow_the_scale(scale_y,scale_x,scale_text)#绘制比例

def drowlegend(ax,x,y,text,step u003d 0.5):

#绘制图例

x是图例左上角的经度;

y是图例左上角的纬度;

text 是文字描述;

step 是间距

drowcircle(ax,((x,y),))#画一个红色圆圈

plt.text(x+step*1.5,y ,text[0],horizontalalignment u003d 'center')

drowcircle(ax,((x,y - step),),edgecolors u003d 'green')#画一个绿色圆圈

plt.text(x+step*1.5,y- step,text[1],horizontalalignment u003d 'center')

drowfork(ax,((x,y - step*2),))#画一个叉子

plt.text(x+step*1.5,y- step*2,text[2],horizontalalignment u003d 'center')

drowbox(ax,((x,y - step*3),))#画正方形

plt.text(x+step*1.5,y- step*3,text[3],horizontalalignment u003d 'center')

drowtriangle(ax,((x,y - step*4),))#画三角形

plt.text(x+step*1.5,y- step*4,text[4],horizontalalignment u003d 'center')

通过

#主函数

如果 __name__ u003du003d '__main__':

points_pentagram u003d [(113.3, 23.23,'Guangzhou')]#五角星坐标和名称

points_circle_red u003d [(116.1, 26.7),(117.1, 27.7)]#红色圆坐标

points_circle_green u003d [(115.1, 25.7),(118.1, 28.7)]#绿色圆坐标

points_fork u003d [(115.1, 26.7),(118.1, 29.7)]#分叉坐标

points_box u003d [(117.1, 26.7),(115.1, 27.7)]#方坐标

points_triangle u003d [(118.1, 26.7),(114.1, 27.7)]#三角坐标

#图例文字说明

text u003d ['大风','冰雹','龙卷风','闪电','强降水']

#地图周围的经纬度

西 u003d 110

东 u003d 125

南 u003d 20

北 u003d 30

#解决中文乱码问题

plt.rcParams['font.sans-serif'] u003d ['SimHei']

#画布设置、投影设置

fig u003d plt.figure(figsizeu003d(16,9.6))

ax u003d fig.add_subplot(111,projection u003d ccrs.PlateCarree())

#边界设置

img_extent u003d [西、东、南、北]

ax.set_extent(img_extent,crs u003d ccrs.PlateCarree())

#浮雕地图导入

fname u003d 'HYP_LR_SR_OB_DR.tif'

ax.imshow(plt.imread(fname), originu003d'upper', transformu003dccrs.PlateCarree(),extentu003d[-180, 180, -90, 90])

#设置经纬度网格和标签,将透明度改为1,就会出现网格alphau003d1

gl u003d ax.gridlines(crsu003dccrs.PlateCarree(), draw_labelsu003dTrue, linewidthu003d1, coloru003d'k', alphau003d0,linestyleu003d'--')#轴设置

gl.xformatter u003d LONGITUDE_FORMATTER ##坐标刻度转换为经纬度样式

gl.yformatter u003d LATITUDE_FORMATTER

#设置经度和纬度的显示,比如经度70到135,间隔5

gl.xlocator u003d mticker.FixedLocator(np.arange(70,135,5))

gl.ylocator u003d mticker.FixedLocator(np.arange(15,55,5))

drowscale(img_extent,21,123.1,'500')#绘制比例

drowpentagram(ax,points_pentagram)#画五颗尖角星

drowcircle(ax,points_circle_red)#画一个红色圆圈

drowcircle(ax,points_circle_green,edgecolors u003d 'green')#画一个绿色圆圈

drowfork(ax,points_fork)#画一个叉子

drowbox(ax,points_box)#画正方形

drowtriangle(ax,points_triangle)#画三角形

drowlegend(ax,123.1,24,text,step u003d 0.5)#绘制图例

plt.show()

五、求助

有朋友知道cartopy自带刻度功能吗?我翻了翻文件,没找到。我的朋友留言帮助我。作者绘制的尺度只有自己的表格,深度不够严谨。

Logo

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐