小白学习Basemap气象画地图的第三天(中国温度分布图,mask外部)

首先还是感谢公众号(气象学家),代码和测试数据来自与他,不过这次有长进了,自己学会修改了。还是逐条向大家解释。
(和大家分享一个经验,在代码中查看某个函数或者变量的定义,可以利用快捷键快速寻找,pycharm里面是ctrl + 鼠标左键点击,这样的意义在于可以定位到最原始的构造函数,定义等位置,从而了解其用法,参数设置。要学会看__init__()里面的东西)
这次是用Basemap库画的,这个库在线安装好像已经停止了,只能下载离线包进行安装了,大家注意一下,首先效果图奉上:

导入库

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch
import numpy as np
import shapefile
import xarray as xr
from mpl_toolkits.basemap import Basemap

绘图区设置

#设置画图字体的大小
plt.rcParams.update({'font.size':20})
#解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['SimHei']
#解决负号乱码问题
plt.rcParams['axes.unicode_minus'] = False
#设置画布和绘图区
fig = plt.figure(figsize=[12,18])
ax = fig.add_subplot(111)

读取地图,设置mask路径(重点)

这里是重点部分,小白容易看不懂,注释比较多,大家不要耐烦,文末作者会给出注释少的代码版本

#读取shp格式的地图,有三个文件分别为.dbf,.shp,.shx缺一不可
#这里的shp文件其实就是一堆点,把各个国家圈出来
#sf得到的是一个类,存放了全球的地理信息
sf = shapefile.Reader("country1")
#sf.shapeRecords()里面放了各个国家地区的信息
#循环的目的是单个拿出来,找到中国  shape_rec是单个
for shape_rec in sf.shapeRecords():#shape_rec.record内部存放了单一国家的很多信息,比如名字,货币等等#其中shape_rec.record[2]放的是国家名#可以print(shape_rec.record)看看if shape_rec.record[2] == 'China':codes = []#用来存放移动路径(画图动作)#shape_rec.shape是一个类,图形类#里面三个属性shapeType:图形类型  points图形边界坐标  parts图形起始索引#解释一下parts属性,一个国家的边界可能不是全连在一起的,会分为一块一块,那么就相当于多个图形,存在shp文件内就不连续,parts里面就放了每个区域的起始索引(下标)pts = shape_rec.shape.points#上文已经说过了parts的意义,设想一下,两块区域的的起始坐标中间夹的不就是一块区域的所有坐标吗,但是最后一块区域没有结束值,所有加了[len(pts)],这就是最后一个点的索引。prt = list(shape_rec.shape.parts) + [len(pts)]#下面的循环主要作用是:建立一个绘图路径,利用区块起始点的索引生成一个画图动作for i in range(len(prt) - 1):codes += [Path.MOVETO]#点移动codes += [Path.LINETO] * (prt[i+1] - prt[i] -2)#画线codes += [Path.CLOSEPOLY]#这块画完,循环结束,下一块clip = Path(pts, codes)#利用数据和路径生成一个画图动作clip = PathPatch(clip, transform=ax.transData)#再加入ax的变换

大致原理是读取地图文件,大家俗称的shp文件,然后利用里面的点,得到一个或者多个画图路径(一般都是多个,国家边界很容易是很多段的),利用这个路径来把路径外部区域全部画成白的。细节可以看代码块的注释。

读取NC数据

这一部分比较简单

#这里是读取NC数据部分,上一个帖子已经介绍了,不再赘述
ds = xr.open_dataset('EC-Interim_monthly_2018.nc')
lat = ds.latitude
lon = ds.longitude
data = (ds['t2m'][0,::-1,:] - 273.15) # 把温度转换为℃   [0,::-1,:]表示第一个时次、纬度反向

画温度分部图

这一部分和之前也大同小异

cbar_kwargs = {'orientation': 'horizontal','label': 'Temperature (℃)','shrink': 0.02,'ticks': np.arange(-25, 25 + 1, 5),'pad': -0.28,'shrink': 0.95
}
levels = np.arange(-25, 25 + 1, 1)
cs = data.plot.contourf(ax=ax,levels=levels,cbar_kwargs=cbar_kwargs, cmap='Spectral_r')

到这里,咱们画出来的全球的温度分补(别忘了plt.show())

利用掩膜路径画中国区域

其实就一条代码,简单的很,拿来用就好了

#添加掩膜路径,白化外部的分部
for contour in cs.collections:contour.set_clip_path(clip)

但是结果出现的问题,因为坐标变换的问题,生成的结果为

利用Basemap类调整图形

#生成一个Basemap类,用来变换坐标,画出合适尺寸的图
m = Basemap(llcrnrlon=72.0,#地图左边经度llcrnrlat=10.0,#地图下方纬度urcrnrlon=137.0,#地图右边经度urcrnrlat=55.0,#地图上方纬度resolution = None,#分辨率,这里设置为无projection = 'cyl')#投影方式:默认,圆柱投影
#读取图形文件,画中国行政边界
m.readshapefile('bou2_4l','China Map',color='k',linewidth=1.2)

readshapefile()函数的作用就是读取bou2_4l文件画图,结果为

图像修饰

在进行一些修饰,让图片更好看

#画纬度
parallels = np.arange(10,55,10)
m.drawparallels(parallels,labels=[True,True,True,True],color='dimgrey',dashes=[1, 3])
#画经度
meridians = np.arange(70,135,10)
m.drawmeridians(meridians,labels=[True,True,False,True],color='dimgrey',dashes=[1, 3])
#移除原来的坐标轴标签
plt.ylabel('')
plt.xlabel('')#设置标题
plt.rcParams.update({'font.size':30})
ax.set_title(u' 中国区域2018年1月平均气温',color='blue',fontsize= 25)#画南海
with open('CN-border-La.dat') as src:context = src.read()blocks = [cnt for cnt in context.split('>') if len(cnt) > 0]borders = [np.fromstring(block, dtype=float, sep=' ') for block in blocks]
sub_ax = fig.add_axes([0.758, 0.249, 0.14, 0.155],projection=ccrs.LambertConformal(central_latitude=90, central_longitude=115))
for line in borders:sub_ax.plot(line[0::2], line[1::2], '-', lw=1, color='k',transform=ccrs.Geodetic())
sub_ax.set_extent([106, 127, 0, 25],crs=ccrs.PlateCarree())

完整代码,注释简洁版

最后有注释详细版,怕大家烦,就放最后了

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch
import numpy as np
import shapefile
import xarray as xr
from mpl_toolkits.basemap import Basemap#设置画图字体的大小
plt.rcParams.update({'font.size':20})
#解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['SimHei']
#解决负号乱码问题
plt.rcParams['axes.unicode_minus'] = False
#设置画布和绘图区
fig = plt.figure(figsize=[12,18])
ax = fig.add_subplot(111)#读取shp格式的地图
sf = shapefile.Reader("country1")
#得到mask白化路径
for shape_rec in sf.shapeRecords():if shape_rec.record[2] == 'China':codes = []pts = shape_rec.shape.points#边界点prt = list(shape_rec.shape.parts) + [len(pts)]#区块起始索引for i in range(len(prt) - 1):codes += [Path.MOVETO]#点移动codes += [Path.LINETO] * (prt[i+1] - prt[i] -2)#画线codes += [Path.CLOSEPOLY]#这块画完,循环结束,下一块clip = Path(pts, codes)#利用数据和路径生成一个画图动作clip = PathPatch(clip, transform=ax.transData)#再加入ax的变换
#########################至此,所需国界图形读取完毕####################
#这里是读取NC数据部分,上一个帖子已经介绍了,不再赘述
ds = xr.open_dataset('EC-Interim_monthly_2018.nc')
lat = ds.latitude
lon = ds.longitude
data = (ds['t2m'][0,::-1,:] - 273.15) # 把温度转换为℃   [0,::-1,:]表示第一个时次、纬度反向
############################至此读取温度数据结束#######################下面画
cbar_kwargs = {'orientation': 'horizontal','label': 'Temperature (℃)','shrink': 0.02,'ticks': np.arange(-25, 25 + 1, 5),'pad': -0.28,'shrink': 0.95
}levels = np.arange(-25, 25 + 1, 1)
cs = data.plot.contourf(ax=ax,levels=levels,cbar_kwargs=cbar_kwargs, cmap='Spectral_r')
#但是画出的全球温度分布
############################至此温度画完了######################
#添加掩膜路径,白化外部的分部
for contour in cs.collections:contour.set_clip_path(clip)#生成一个Basemap类,用来变换坐标,画出合适尺寸的图
m = Basemap(llcrnrlon=72.0,#地图左边经度llcrnrlat=10.0,#地图下方纬度urcrnrlon=137.0,#地图右边经度urcrnrlat=55.0,#地图上方纬度resolution = None,#分辨率,这里设置为无projection = 'cyl')#投影方式:默认,圆柱投影#读取图形文件,画中国行政边界
m.readshapefile('bou2_4l','China Map',color='k',linewidth=1.2)
######################至此图基本画完了,下面是一些修饰过程######################
#画纬度
parallels = np.arange(10,55,10)
m.drawparallels(parallels,labels=[True,True,True,True],color='dimgrey',dashes=[1, 3])
#画经度
meridians = np.arange(70,135,10)
m.drawmeridians(meridians,labels=[True,True,False,True],color='dimgrey',dashes=[1, 3])
#移除原来的坐标轴标签
plt.ylabel('')
plt.xlabel('')
#设置标题
plt.rcParams.update({'font.size':30})
ax.set_title(u' 中国区域2018年1月平均气温',color='blue',fontsize= 25)
#画南海
with open('CN-border-La.dat') as src:context = src.read()blocks = [cnt for cnt in context.split('>') if len(cnt) > 0]borders = [np.fromstring(block, dtype=float, sep=' ') for block in blocks]
sub_ax = fig.add_axes([0.758, 0.249, 0.14, 0.155],projection=ccrs.LambertConformal(central_latitude=90, central_longitude=115))
for line in borders:sub_ax.plot(line[0::2], line[1::2], '-', lw=1, color='k',transform=ccrs.Geodetic())
sub_ax.set_extent([106, 127, 0, 25],crs=ccrs.PlateCarree())
######################修饰完毕,出图######################
plt.savefig("China_mask_T2m.png", dpi=300, bbox_inches='tight')
plt.show()

完整代码,注释详细版

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch
import numpy as np
import shapefile
import xarray as xr
from mpl_toolkits.basemap import Basemap#设置画图字体的大小
plt.rcParams.update({'font.size':20})
#解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['SimHei']
#解决负号乱码问题
plt.rcParams['axes.unicode_minus'] = False
#设置画布和绘图区
fig = plt.figure(figsize=[12,18])
ax = fig.add_subplot(111)#读取shp格式的地图,有三个文件分别为.dbf,.shp,.shx缺一不可
#这里的shp文件其实就是一堆点,把各个国家圈出来
#sf得到的是一个类,存放了全球的地理信息
sf = shapefile.Reader("country1")
#sf.shapeRecords()里面放了各个国家地区的信息
#循环的目的是单个拿出来,找到中国  shape_rec是单个
for shape_rec in sf.shapeRecords():#shape_rec.record内部存放了单一国家的很多信息,比如名字,货币等等#其中shape_rec.record[2]放的是国家名#可以print(shape_rec.record)看看if shape_rec.record[2] == 'China':codes = []#用来存放移动路径(画图动作)#shape_rec.shape是一个类,图形类#里面三个属性shapeType:图形类型  points图形边界坐标  parts图形起始索引#解释一下parts属性,一个国家的边界可能不是全连在一起的,会分为一块一块,那么就相当于多个图形,存在shp文件内就不连续,parts里面就放了每个区域的起始索引(下标)pts = shape_rec.shape.points#上文已经说过了parts的意义,设想一下,两块区域的的起始坐标中间夹的不就是一块区域的所有坐标吗,但是最后一块区域没有结束值,所有加了[len(pts)],这就是最后一个点的索引。prt = list(shape_rec.shape.parts) + [len(pts)]#下面的循环主要作用是:建立一个绘图路径,利用区块起始点的索引生成一个画图动作for i in range(len(prt) - 1):codes += [Path.MOVETO]#点移动codes += [Path.LINETO] * (prt[i+1] - prt[i] -2)#画线codes += [Path.CLOSEPOLY]#这块画完,循环结束,下一块clip = Path(pts, codes)#利用数据和路径生成一个画图动作clip = PathPatch(clip, transform=ax.transData)#再加入ax的变换#########################至此,所需国界图形读取完毕#####################这里是读取NC数据部分,上一个帖子已经介绍了,不再赘述
ds = xr.open_dataset('EC-Interim_monthly_2018.nc')
lat = ds.latitude
lon = ds.longitude
data = (ds['t2m'][0,::-1,:] - 273.15) # 把温度转换为℃   [0,::-1,:]表示第一个时次、纬度反向
############################至此读取温度数据结束#######################下面画
cbar_kwargs = {'orientation': 'horizontal','label': 'Temperature (℃)','shrink': 0.02,'ticks': np.arange(-25, 25 + 1, 5),'pad': -0.28,'shrink': 0.95
}levels = np.arange(-25, 25 + 1, 1)
cs = data.plot.contourf(ax=ax,levels=levels,cbar_kwargs=cbar_kwargs, cmap='Spectral_r')
#但是画出的全球温度分布
############################至此温度画完了######################
#添加掩膜路径,白化外部的分部
for contour in cs.collections:contour.set_clip_path(clip)#生成一个Basemap类,用来变换坐标,画出合适尺寸的图
m = Basemap(llcrnrlon=72.0,#地图左边经度llcrnrlat=10.0,#地图下方纬度urcrnrlon=137.0,#地图右边经度urcrnrlat=55.0,#地图上方纬度resolution = None,#分辨率,这里设置为无projection = 'cyl')#投影方式:默认,圆柱投影#读取图形文件,画中国行政边界
m.readshapefile('bou2_4l','China Map',color='k',linewidth=1.2)
######################至此图基本画完了,下面是一些修饰过程######################
#画纬度
parallels = np.arange(10,55,10)
m.drawparallels(parallels,labels=[True,True,True,True],color='dimgrey',dashes=[1, 3])
#画经度
meridians = np.arange(70,135,10)
m.drawmeridians(meridians,labels=[True,True,False,True],color='dimgrey',dashes=[1, 3])
#移除原来的坐标轴标签
plt.ylabel('')
plt.xlabel('')#设置标题
plt.rcParams.update({'font.size':30})
ax.set_title(u' 中国区域2018年1月平均气温',color='blue',fontsize= 25)#画南海
with open('CN-border-La.dat') as src:context = src.read()blocks = [cnt for cnt in context.split('>') if len(cnt) > 0]borders = [np.fromstring(block, dtype=float, sep=' ') for block in blocks]
sub_ax = fig.add_axes([0.758, 0.249, 0.14, 0.155],projection=ccrs.LambertConformal(central_latitude=90, central_longitude=115))
for line in borders:sub_ax.plot(line[0::2], line[1::2], '-', lw=1, color='k',transform=ccrs.Geodetic())
sub_ax.set_extent([106, 127, 0, 25],crs=ccrs.PlateCarree())######################修饰完毕,出图######################
plt.savefig("China_mask_T2m.png", dpi=300, bbox_inches='tight')
plt.show()

测试数据和文件需要的请下面留言,感谢支持

小白学习Basemap气象画地图的第三天(中国温度分布图,mask外部)相关推荐

  1. 小白学习Basemap气象画地图的第五天(读取micaps站点数据,省级能见度分布)

    小白学习Basemap气象画地图的第五天(读取micaps站点数据,省级能见度分布) 这一帖子,主要介绍了三个重点: 1.micaps站点数据的读取 2.站点数据的插值 3.不均匀色标的生成 在下面的 ...

  2. 小白学习Basemap气象画地图的第四天(省级温度分布)

    小白学习Basemap气象画地图的第四天(省级温度分布) 经过四个案例的学习,有了很大的进步,感谢(公众号:气象学家) 这次画一个省级温度分布,原理和程序与之前的全国一样,这里就不多说了,可以看注释, ...

  3. 小白学习cartopy画地图的第一天(中国行政区域图,含南海)

    小白学习cartopy画地图的第一天(中国行政区域图,含南海) 这是地图小白的我学习用cartopy画地图的第一天,慢慢摸索慢慢学习,一步一步学会使用cartopy.后面会持续更新.其中很多是从各个博 ...

  4. python海洋绘图-Basemap库画地图时,南极洲显示不全

    问题叙述 在利用Basemap库进行全球地图绘制时,发现一个很奇怪的问题:南极洲部分显示异常. 输入代码为: m = Basemap(projection = 'cyl') # 画海岸线 m.draw ...

  5. 小白学习运维要想明白的三个问题

    一.学习运维要理清的三个问题 1.1.第一个问题,我能不能学运维 学习运维的人分为三类: 第一类: 科班出身,但是没有运维经验的应届本科或者专科 这类学员已经有了计算机基础,原则上不建议报培训班,直接 ...

  6. 阻止地图的放大和缩小_Arcgis画地图详细步骤(真的!!)

    在学习了python画地图之后,继续进行地图的学习,Arcgis画地图的详细步骤来也!!! 1.打开Arcgis点击取消 2.点击添加数据 3.导入shp文件:找到电脑中shp文件的位置,单击选择之后 ...

  7. python使用pyecharts库画地图数据可视化

    python使用pyecharts库画地图数据可视化 导库 中国地图 代码 结果 世界地图 代码 结果 省级地图 代码 结果 地级市地图 代码 结果 导库 from pyecharts import ...

  8. 小白学习cartopy画地图的第六天

    小白学习cartopy画地图的第六天 从开始学习画地图开始,就是打算用cartopy的,但是不知不觉跑偏了,跑去了Basemap,最近感觉这样不对,因为Basemap已经停止更新了,主要还是个人觉得c ...

  9. echarts geo地图示例_python小白的画地图合集(使用pyecharts)

    经过今晚的小摸索,终于可以画出世界地图.省级地图以及全国的热力图.所以特此决定出一个小的合集,建议先去阅读上一篇写的画中国地图,可能那样子你会很快速了解到画图的精髓. 画世界地图 依旧是上次的套路: ...

最新文章

  1. mac os x 添加 用户 所属 组
  2. AXI quad SPI没有输出
  3. 体二极管的原理及应用
  4. SAP Spartacus的PWA支持
  5. Connect 2016过后,你的信仰势必需要更大的容器
  6. Python小白的数学建模课-B3. 新冠疫情 SIS模型
  7. CVPR 2018 paper list(论文列表)
  8. 我的Go+语言初体验——Go+语言构建神经网络实战手写数字识别
  9. 搞清字符集和字符编码
  10. su and sudo
  11. 设备驱动基础1:设备模型之总线,驱动,设备
  12. What is the Actual Performance of HANA?
  13. SG平滑轨迹算法的原理和实现
  14. 学以致用——Java源码——抛双骰儿游戏综合评估(游戏步数与胜率的关系,公平性,平均步数等)(Game of Craps Evaluation)
  15. coutendl;什么意思?
  16. 中职计算机应用教学的重要性,中职《计算机应用基础》教学中理实一体化的有效开展...
  17. 同时支持手机号、用户名、邮箱登录
  18. JNI详解---从不懂到理解
  19. 渗透测试之Windows基础(新手必看)
  20. 数据分析知识体系与校招时间线

热门文章

  1. 关于tiktok环境伪装度检测升级!
  2. python的from_bytes属性_(转)python之from_bytes、to_bytes
  3. Linux命令的分类
  4. linux搭建Dbus教程
  5. 商业智能报表--杜邦分析仪
  6. java万年历开题报告_基于单片机的万年历开题报告.doc
  7. 如何建立一个 [FTP站点 or HTTP站点] 去实现资源共享
  8. android-设置状态栏与标题栏背景
  9. connectify 3.1pro教程
  10. 基于模糊控制技术的汽车空调半导体制冷片送风控制系统研究