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

这一帖子,主要介绍了三个重点:
1.micaps站点数据的读取
2.站点数据的插值
3.不均匀色标的生成
在下面的介绍中一一解释

读取micaps站点数据

这一步暂时不做解释了,因为光解释这个可以开一帖,代码是我网上找到,不是自己写的。其实大家不用纠结是否能看懂,能用就好了。

import struct
import datetime
import pickle
def create_dict(_dict, index):if index not in _dict.keys():_dict[index] = list()
corr_dtype = {1:'x', 2:'h', 3:'i', 4:'l', 5:'f', 6:'d', 7:'s'}
corr_size = {1:1, 2:2, 3:4, 4:4, 5:4, 6:8, 7:1}
buf = open('data_table.pickle', 'rb')
var_table = pickle.load(buf)
buf.close()
class MDFS_Station:def __init__(self, filepath):f = open(filepath, 'rb')if f.read(4).decode() != 'mdfs':raise ValueError('Not valid mdfs data')# Headerdtype = struct.unpack('h', f.read(2))[0]self.data_dsc = f.read(100).decode('gbk').replace('\x00', '')self.level = struct.unpack('f', f.read(4))[0]self.level_dsc = f.read(50).decode('gbk').replace('\x00', '')year, month, day, hour, min_, sec, tz = struct.unpack('7i', f.read(28))self.utc_time = datetime.datetime(year, month, day, hour, min_, sec) - datetime.timedelta(hours=tz)f.seek(100, 1)#288# Data block 1station_num = struct.unpack('i', f.read(4))[0] #292# Data block 2quantity_num = struct.unpack('h', f.read(2))[0] #294x = dict([(struct.unpack('h', f.read(2))[0], struct.unpack('h', f.read(2))[0]) for i in range(quantity_num)])# Data block 3data = {}for i in ['ID', 'Lon', 'Lat']:create_dict(data, i)for i in x.keys():create_dict(data, i)for _ in range(station_num):stid, stlon, stlat = struct.unpack('iff', f.read(12))data['ID'].append(stid)data['Lon'].append(stlon)data['Lat'].append(stlat)q_num = struct.unpack('h', f.read(2))[0]id_list = list()# iterate over q_numfor __ in range(q_num):var_id = struct.unpack('h', f.read(2))[0]if var_id % 2 == 0 and var_id not in range(22):var_info = 1else:var_info = var_table[var_id]id_list.append(var_id)var_value = struct.unpack(corr_dtype[var_info], f.read(corr_size[var_info]))if var_value and var_id % 2 != 0:var_value = var_value[0]data[var_id].append(var_value)# print(x.keys())for i in x.keys():if i not in id_list:# data[i].append(np.nan)data[i].append(None)self.data = data

主要是MDFS_Station()类

正式开始

第一步导入类

from read_mdfs import MDFS_Station#另外写的一个类,用于读取micaps数据,当然不是我写的,抄的,忘记出处了,不好意思
import numpy as np
from scipy.interpolate import Rbf
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch
import matplotlib.colors as mcolors
import shapefile
from mpl_toolkits.basemap import Basemap
import matplotlib as mpl

第二步读取micaps站点数据(重点)

x = MDFS_Station('20210210100000.000')
#读出的x是一个字典
#经纬度,每一个是一个list
lon = x.data['Lon']
lat = x.data['Lat']
#数据,1207代码代表了【水平能见度(人工)】,micaps数据各代码含义可以自行寻找
var = x.data[1207]

这里读取的是’20210210100000.000’是micaps站点数据。
说明:
站点数据和格点的区别:格点数据是有规律排列的比如1°*1°就是一个经度一个纬度一个数据,是网格点。
站点数据就是观测站提供的数据,观测站的分部无法很规律,类似于离散的点
画站点数据需要进行插值,插值成格点数据进行画图,下面会提到
关于micaps数据各代码含义可以留下邮箱或者网盘,作者给发micaps数据结构

第三步插值成格点数据(重点)

插值经纬度

对经纬度进行插值,这里作者讲经纬度插值成了0.05°*0.05°的网格

olon = np.linspace(108,115,140)
olat = np.linspace(24,31,140)
olon,olat = np.meshgrid(olon,olat)

np.meshgrid(),将两个一维数组合成一个二维的网格坐标矩阵,就是把经纬度的两个list变成有关系的二维经纬网格

插值数据

生成一个插值规则

func = Rbf(lon,lat,var,function='cubic')

Rbf()是一种插值函数,好像是径向插值什么的,字面理解的意思应该就是以这一点开始,向外插值。
function=‘cubic’,就是插值的方式,列举了三种linear、cubic、gaussian。
gaussian作者的电脑比较烂,跑崩了,大家可以试一试。
另外两种作者下面有效果,自己看。
其他的就自己去摸索啦。

#根据插值规则生成新的数据,得到格点数据
var_new1 = func(olon,olat)
#筛选数据,把因为插值造成的小于0,大于30的数据变回0和30
var_new1[var_new1 < 0] = 0
var_new1[var_new1 > 30] = 30

第四步画图

图像设置,读取地图文件在这里不再介绍,可以看作者之前的帖子,有详细的说明
主要解释不均匀色板的生成
设置不均匀的色板的原因在于,如果使用均匀的色板,从能见度200m到30km均匀等分,图像不美观,能见度差的区域也不够凸显

设置层次

#设置层次,仔细看可以发现间隔是不均匀的(抄的micaps)
clevs = [0.00, 0.20,0.50,1.00,2.00,3.00,5.00,10.00,20.00,30.00]

建立对应的颜色列表

#建立对应的颜色列表(抄的micaps)
cdict = ['#6f2800','#9c00ff','#fe0100','#fc5506','#fbb249','#ffff00','#75ff30','#92e0f8','#c9ecff']
#利用颜色列表生成一个cmap类,用于画图
my_cmap = mcolors.ListedColormap(cdict)

归一化颜色

#BoundaryNorm是数据分组中数据归一化比较好的方法
#意思就是把层次全部归一化到0-1,然后映射到颜色上,比较抽象,如果不理解也没事,照葫芦画瓢,照做就好了
norm = mcolors.BoundaryNorm(clevs,my_cmap.N)

画图画色板

#画图
cs = ax.contourf(olon,olat,var_new1,levels=clevs, cmap=my_cmap,norm =norm )
#画色板
plt.rcParams.update({'font.size':10})
plt.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=my_cmap), ax = ax, label='能见度(km)')

第五步画掩膜,美化图片

这一步也不做详细解释了,前期的帖子也有,大家可以去看

#mask掩膜
for contour in cs.collections:contour.set_clip_path(clip)
#创建Basemap类
m = Basemap(llcrnrlon=108.0,#地图左边经度llcrnrlat=24.0,#地图下方纬度urcrnrlon=115.0,#地图右边经度urcrnrlat=31.0,#地图上方纬度resolution = None,#分辨率,这里设置为无projection = 'cyl')#投影方式:默认,圆柱投影
#画省界和地级市界
m.readshapefile('Hunan_Province','Map',color='k',linewidth=1.2)
m.readshapefile('Hunan_city','city Map',color='k',linewidth=1.2)#画纬度
plt.rcParams.update({'font.size':10})
parallels = np.arange(23,32,1)
m.drawparallels(parallels,labels=[True,True,True,True],color='dimgrey',dashes=[1, 3])
#画经度
meridians = np.arange(108.5,115,1)
m.drawmeridians(meridians,labels=[True,True,False,True],color='dimgrey',dashes=[1, 3])
#移除原来的坐标轴标签
plt.ylabel('')
plt.xlabel('')
#设置标题
plt.rcParams.update({'font.size':20})
ax.set_title(u'湖南省2021年2月10日10时能见度',color='blue',fontsize= 25)bill2 =  113.0
tip2  = 28.21
plt.scatter(bill2, tip2,marker='*',s=150 ,color ="orange" )#画个点plt.rcParams.update({'font.size':20})
plt.text(bill2+0.2, tip2, u"长沙市", fontsize= 20 )#在斜上方写个字plt.show()

出图

function=‘cubic’

function=‘linear’

完整代码

from read_mdfs import MDFS_Station#另外写的一个类,用于读取micaps数据,当然不是我写的,抄的,忘记出处了,不好意思
import numpy as np
from scipy.interpolate import Rbf
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch
import matplotlib.colors as mcolors
import shapefile
from mpl_toolkits.basemap import Basemap
import matplotlib as mpl#-------------读取micaps数据,读取的站点数据-----------
#站点数据和格点的区别:格点数据是有规律排列的比如1°*1°就是一个经度一个纬度一个数据,是网格点
#站点数据就是观测站提供的数据,观测站的分部无法很规律,类似于离散的点
#画站点数据需要进行插值,插值成格点数据进行画图,下面会提到
x = MDFS_Station('20210210100000.000')
#读出的x是一个字典
#经纬度,每一个是一个list
lon = x.data['Lon']
lat = x.data['Lat']
#数据,1207代码代表了【水平能见度(人工)】,micaps数据各代码含义可以自行寻找
var = x.data[1207]#-------------插值成格点数据-(这里是重点)----------
#对经纬度进行插值,这里作者讲经纬度插值成了0.05°*0.05°的网格
olon = np.linspace(108,115,140)
olat = np.linspace(24,31,140)
#np.meshgrid(),将两个一维数组合成一个二维的网格坐标矩阵,就是把经纬度的两个list变成有关系的二维经纬网格
olon,olat = np.meshgrid(olon,olat)#Rbf()是一种插值函数,好像是径向插值什么的,字面理解的意思应该就是以这一点开始,向外插值
#function='cubic',就是插值的方式,列举了三种linear、cubic、gaussian
#gaussian作者的电脑比较烂,跑崩了,大家可以试一试
#另外两种作者下面有效果,自己看
#其他的就自己去摸索啦
func = Rbf(lon,lat,var,function='cubic')
#对var进行插值,得到格点var_new1
var_new1 = func(olon,olat)
#筛选数据,把因为插值造成的小于0,大于30的数据变回0和30
var_new1[var_new1 < 0] = 0
var_new1[var_new1 > 30] = 30#-------------开始画图-----------
#解决中文乱码问题
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('Hunan_Province')#读取shp地图文件
shapes = sf.shapes()#获取shapefile的类
codes = []#用来存放移动路径(画图动作)
pts = shapes[0].points#边界点,这里只有一个类所以用了shapes[0],没做循环
prt = list(shapes[0].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的变换#这里是重点,设置不均匀的色板(原因在于,如果使用均匀的色板,从能见度200m到30km均匀等分,图像不美观,能见度差的区域也不够凸显)
#设置层次,仔细看可以发现间隔是不均匀的(抄的micaps)
clevs = [0.00, 0.20,0.50,1.00,2.00,3.00,5.00,10.00,20.00,30.00]
#建立对应的颜色列表(抄的micaps)
cdict = ['#6f2800','#9c00ff','#fe0100','#fc5506','#fbb249','#ffff00','#75ff30','#92e0f8','#c9ecff']
#利用颜色列表生成一个cmap类,用于画图
my_cmap = mcolors.ListedColormap(cdict)
#BoundaryNorm是数据分组中数据归一化比较好的方法
#意思就是把层次全部归一化到0-1,然后映射到颜色上,比较抽象,如果不理解也没事,照葫芦画瓢,照做就好了
norm = mcolors.BoundaryNorm(clevs,my_cmap.N)
#画图
cs = ax.contourf(olon,olat,var_new1,levels=clevs, cmap=my_cmap,norm =norm )
#画色板
plt.rcParams.update({'font.size':10})
plt.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=my_cmap), ax = ax, label='能见度(km)')#mask掩膜
for contour in cs.collections:contour.set_clip_path(clip)
#创建Basemap类
m = Basemap(llcrnrlon=108.0,#地图左边经度llcrnrlat=24.0,#地图下方纬度urcrnrlon=115.0,#地图右边经度urcrnrlat=31.0,#地图上方纬度resolution = None,#分辨率,这里设置为无projection = 'cyl')#投影方式:默认,圆柱投影
#画省界和地级市界
m.readshapefile('Hunan_Province','Map',color='k',linewidth=1.2)
m.readshapefile('Hunan_city','city Map',color='k',linewidth=1.2)#画纬度
plt.rcParams.update({'font.size':10})
parallels = np.arange(23,32,1)
m.drawparallels(parallels,labels=[True,True,True,True],color='dimgrey',dashes=[1, 3])
#画经度
meridians = np.arange(108.5,115,1)
m.drawmeridians(meridians,labels=[True,True,False,True],color='dimgrey',dashes=[1, 3])
#移除原来的坐标轴标签
plt.ylabel('')
plt.xlabel('')
#设置标题
plt.rcParams.update({'font.size':20})
ax.set_title(u'湖南省2021年2月10日10时能见度',color='blue',fontsize= 25)bill2 =  113.0
tip2  = 28.21
plt.scatter(bill2, tip2,marker='*',s=150 ,color ="orange" )#画个点plt.rcParams.update({'font.size':20})
plt.text(bill2+0.2, tip2, u"长沙市", fontsize= 20 )#在斜上方写个字plt.show()

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

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

    小白学习Basemap气象画地图的第三天(中国温度分布图,mask外部) 首先还是感谢公众号(气象学家),代码和测试数据来自与他,不过这次有长进了,自己学会修改了.还是逐条向大家解释. (和大家分享一 ...

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

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

  3. matlab统计文本数据画直方图,matlab从txt中读取某列数据画直方图

    今天本来出去吃饭,回来准备咸鱼躺,结果室友问我matlab的直方图的问题,那就把首次博客内容定为直方图吧.txt中部分数据: 10000000 1E-09 1E-09 -0.0002816916 0. ...

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

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

  5. 学习Spring Boot:(二十五)使用 Redis 实现数据缓存

    前言 由于 Ehcache 存在于单个 java 程序的进程中,无法满足多个程序分布式的情况,需要将多个服务器的缓存集中起来进行管理,需要一个缓存的寄存器,这里使用的是 Redis. 正文 当应用程序 ...

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

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

  7. 基于深度学习框架的火灾识别报警平台搭建----OpenCV3.1.0读取dav视频数据出错

    在搭建深度学习-caffe框架时,使用OpenCV3.1.0读取dav视频数据,出现解析h264数据错误: [h264 ] top block unavailable for requested in ...

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

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

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

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

最新文章

  1. 栈的应用就进匹配_笔记
  2. python穷举法搬砖_python 穷举法 算24点(史上最简短代码)-阿里云开发者社区
  3. 中学计算机科学教育,计算机科学教育周 – Tsinghua International School 清华大学附属中学国际部...
  4. centos7 升级curl版本
  5. oracle修改filesystem,(转):oracle、filesystem、backup日常巡检脚本
  6. idea下以及git如何快速切换remote远端服务器
  7. js动态创建元素和删除
  8. 以太坊创世区块源码分析
  9. WPS(Word)中图注、域的使用基础
  10. word自己新建样式,怎么加入目录?
  11. 计算机硬件运行维护论文,计算机硬件维护毕业论文.doc
  12. TCR历史期刊为何受大家欢迎?
  13. zookeeper之watcher
  14. openwrt广告屏蔽大师修复补丁luci-app-adbyby plus + lite
  15. 老外常用的网络英文缩写
  16. [重庆思庄每日技术分享]-oracle11g到ORACLE 816的dblink访问报 ORA-03150错误
  17. 从“闪电战”到全面战:荣耀开启“吓人的技术”2.0时代
  18. oracle查询的默认排序,oracle 默认排序及认知
  19. turtle风轮绘制(turtle库初学)
  20. maven简便方法跳过打包检查

热门文章

  1. 51单片机:共阴数码管动态显示(定时器+中断)
  2. wireless_ultimate技术所得
  3. TX2 4.6.1 全部软件环境刷机要点
  4. python中什么是不等长编码_2021学堂云计算机科学和Python编程导论(自主模式)期末答案...
  5. Excel表格中如何快速插入多个空白行
  6. 美团App 插件化实践
  7. “熊孩子”乱敲键盘攻破 Linux 桌面;苹果开源代码被发现包含兼容微信的代码;网传蚂蚁启用OKR替代KPI | EA周报...
  8. 零界之痕30号服务器维护,零界之痕12月9日更新了什么 12月9日更新维护公告介绍...
  9. [软考]项目目标VS项目基准
  10. proxy 状态代码503_HTTP状态503错误代码及其解决方法?