爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 448411|回复: 464

[经验总结] Python完美白化

  [复制链接]

新浪微博达人勋

发表于 2016-3-4 20:29:02 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
本帖最后由 平流层的萝卜 于 2022-11-16 21:24 编辑

Python白化似乎是一个不那么容易的问题,不过这个问题相信现在已经得到了完美的解决。借助Basemap和pyshp这两个模块,实现对任意shp文件的区域进行白化,拒绝空白锯齿,甩开越界填图,让maskout后的数据完美吻合shp边界。


                               
登录/注册后可看大图



具体的思路是,读取气象场数据,照常画图,得到matplotlib plot的一个instance,对应未白化的整图。然后进行关键的一步,读取shapefile(shp文件,比如meteoinfo的地图库文件country1.shp,是世界各国地图),提取shapefile里的感兴趣区(比如中国),形成一个clip对象,最后得到剪切图


                               
登录/注册后可看大图


效果图如下:一张海平面气压场的图,把中国外的地区maskout了。
111.png
放大之后来看,没有锯齿,完美吻合。
figure_1.png
当然,也可以把县级地图叠加到上面去,只要保留clip对象不要动,同时叠加更加精细的县级底图就可以了。
111_county.png

第一张图的脚本如下(其他图大同小异):
  1. #coding=utf-8
  2. import maskout
  3. from mpl_toolkits.basemap import Basemap
  4. import matplotlib.pyplot as plt
  5. from matplotlib.font_manager import FontProperties
  6. import numpy
  7. import netCDF4 as nc
  8. font = FontProperties(fname=r"C:\\Windows\\Fonts\\impact.ttf")
  9. font1 = FontProperties(fname=u"C:\\Windows\\Fonts\\simkai.ttf")
  10. fig = plt.figure(figsize=(16,9.6))
  11. ax = fig.add_subplot(111)
  12. # ncdata=nc.Dataset(r'2004_500_grtuvw.nc')
  13. ncdata=nc.Dataset('pres.mon.ltm.nc')
  14. # data=ncdata.variables['t'][0,:,:]
  15. data=ncdata.variables['pres'][0,:,:]
  16. # exit()
  17. # lat=ncdata.variables['latitude'][:]
  18. # lon=ncdata.variables['longitude'][:]
  19. lat=ncdata.variables['lat'][:]
  20. lon=ncdata.variables['lon'][:]
  21. lon1,lon2=lon[0],lon[-1]
  22. lat1,lat2=lat[-1],lat[0]
  23. nx=data.shape[1];ny=data.shape[0]
  24. m = Basemap(llcrnrlon=lon1,llcrnrlat=lat1,urcrnrlon=lon2,urcrnrlat=lat2,projection = 'cyl')
  25. xx,yy=m.makegrid(nx,ny)
  26. yy=yy[::-1]
  27. m.readshapefile('country1','whatevername',color='gray')
  28. minval,maxval=int(numpy.amin(data)),int(numpy.amax(data))+1
  29. cs = m.contourf(xx,yy,data,range(minval,maxval),cmap= plt.cm.get_cmap('jet') )
  30. bar=m.colorbar(cs)
  31. bar.set_ticks(range(minval-1,maxval,40))
  32. bar.set_ticklabels(range(minval-1,maxval,40))
  33. clip=maskout.shp2clip(cs,ax,'country1','China')
  34. plt.title(u'Python Super Mask',fontproperties=font,fontsize=40)
  35. lon1,lon2=ax.set_xlim(70,140);lat1,lat2=ax.set_ylim(15,55)
  36. #signature=u"by 平流层的萝卜"
  37. #plt.text(lon2-(lon2-lon1)*3.0/10,lat2+(lat2-lat1)*0.1/10,signature,fontproperties=font1,fontsize=25)
  38. # plt.show()
  39. plt.savefig('111.png')
复制代码
对于上面的clip=maskout.shp2clip(cs,ax,'country1','China') ,其中maskout是自己定义的一个模块,实现的功能就是最关键的对整图进行剪切,因为模块可以移植到其他程序中,方便以后使用。
把第一张图的测试数据、地图和脚本一块打包了,包括自定义maskout模块包,欢迎感兴趣的朋友下载: Python完美白化_测试数据及脚本.rar (1.41 MB, 下载次数: 4553)

评分

参与人数 16金钱 +181 贡献 +15 体力 +200 收起 理由
Franny + 10
Om_MyGad + 10 很给力!
huanglii + 2 很给力!
上善若水任方圆 + 10 很给力!
veelam + 8
神奇小宝包 + 20 很给力!
峰巅疯癫 + 1 很给力!
mofangbao + 20 + 5
落木萧骁 + 6 很给力!
邺下放歌 + 20 很给力!
非对称 + 20 + 2 很给力!
nhri8888 + 1 我想知道,我把坐标系改成了等积圆锥投影之.
刘包包 + 10 赞一个!
Jack_TEA + 1 很给力!
又是那隻貓 + 22 + 6 + 200
po_po1 + 20 + 2 太帅了!

查看全部评分

本帖被以下淘专辑推荐:

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-3-22 17:02:52 | 显示全部楼层
本帖最后由 lovechang1314 于 2016-3-22 17:06 编辑

简单测试了以下,可以用。
有个问题,projection='cyl' 应该是不需要转换坐标的吧?
如果用'stere'这个时候画图的时候需要  转换坐标,这个时候就没办法clip,可否把坐标转换的代码加入到你的脚本之中?
比如
x= np.arange(70,140.1, 0.5)
y= np.arange(20,70.1,0.5)
lon,lat=np.meshgrid(x,y)
inlon, inlat = m(lon, lat)
那么在maskout.py中读取shp文件的点时就进行转换在append,这样应该就可以了吧?
如图: basemap.jpg
basemap2.jpg
C:\Users\Administrator\Desktop\basemap.png
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2016-3-23 10:18:21 | 显示全部楼层
lovechang1314 发表于 2016-3-22 17:02
简单测试了以下,可以用。
有个问题,projection='cyl' 应该是不需要转换坐标的吧?
如果用'stere'这个时 ...

非常好的建议。当时没有考虑到投影的问题,我再测试一下,改一改。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-5-4 21:42:41 | 显示全部楼层
关于只画海上的学习,参照楼主的教程,选用高精度的海洋数据(10m_ocean.shp)
111.png
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2017-5-30 08:31:46 | 显示全部楼层

@staticmethod
def MergePaths(paths):
    # paths为path对象列表数组
    path = Path.make_compound_path(*paths)
    return path
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2020-8-31 16:28:58 | 显示全部楼层
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xba in position 0: invalid start byte
请问总是报这样的错是什么原因?
密码修改失败请联系微信:mofangbao
回复 支持 12 反对 0

使用道具 举报

新浪微博达人勋

发表于 2020-10-19 12:37:58 | 显示全部楼层
平流层的萝卜 发表于 2020-10-18 09:44
clip没有被赋值,请参见我帖子内容的结尾部分

我已经找到原因了楼主,在您最初的maskout里面用的命令是“if shape_rec.record[7] == region:”,这样就只能mask一个省,如果把命令改成“if shape_rec.record[7] in region:”就可以使用list,mask多个省了
密码修改失败请联系微信:mofangbao
回复 支持 2 反对 0

使用道具 举报

新浪微博达人勋

发表于 2016-3-5 11:20:59 | 显示全部楼层
赞,感谢分享!
密码修改失败请联系微信:mofangbao
回复 支持 0 反对 2

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2018-6-14 13:55:32 | 显示全部楼层
夭夭坂田淘 发表于 2018-6-13 20:11
还得再麻烦一下楼主。。。我把maskout.py放在和我的脚本同一个文件夹里,但是import maskout后,仍提示“No ...

额,不好用么?那就放在你的python安装目录下的\Lib\site-packages下,再试试
密码修改失败请联系微信:mofangbao
回复 支持 1 反对 0

使用道具 举报

新浪微博达人勋

发表于 2022-10-10 15:58:12 | 显示全部楼层
下载都是php文件,打不开怎么办,下载了好几遍
密码修改失败请联系微信:mofangbao
回复 支持 1 反对 0

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2020-4-14 19:03:10 | 显示全部楼层
偷影子的人 发表于 2020-4-14 14:46
楼主,我想画在兰伯特投影的图上,但是我改了程序之后,maskout按你说的改了,然后主程序里改了clip那里, ...

数据的投影方式这一块,你是否指 xx,yy=m(xx,yy) 这里?确保这个要写上去。
密码修改失败请联系微信:mofangbao
回复 支持 1 反对 0

使用道具 举报

新浪微博达人勋

发表于 2020-4-14 14:46:27 | 显示全部楼层
楼主,我想画在兰伯特投影的图上,但是我改了程序之后,maskout按你说的改了,然后主程序里改了clip那里,还有 m=Basemap(projection = 'laea', lat_0 = 33, lon_0 = 102., lat_ts = 33, width = 7000000, height = 5000000, resolution = 'l'),
但我这样写了之后,画出图来是空白的。
是什么原因呢?我看网上有人说“数据的投影方式也要改”,我对这个不是很明白,能问一下您具体应该怎么做吗?
密码修改失败请联系微信:mofangbao
回复 支持 1 反对 0

使用道具 举报

新浪微博达人勋

发表于 2016-3-4 20:49:22 | 显示全部楼层
赞一个,不错{:5_213:}
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-3-4 20:51:21 | 显示全部楼层
支持原创,十分有用
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-3-4 21:43:25 | 显示全部楼层
{:5_213:}虽然不用Python,但是图好漂亮
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-3-4 23:17:24 | 显示全部楼层
好棒,很强大👍
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-3-5 00:07:48 | 显示全部楼层
腻害!!!
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

发表于 2016-3-5 08:39:41 | 显示全部楼层
你的帅气惊动了玉帝哥哥!!
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-3-5 10:05:40 | 显示全部楼层
{:5_213:}好东西啊
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

发表于 2016-3-5 10:16:40 | 显示全部楼层
厉害,厉害!!
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表