爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 50713|回复: 20

[经验总结] matplotlib+cartopy画WRF小时降水

[复制链接]

新浪微博达人勋

发表于 2020-4-24 11:48:43 | 显示全部楼层 |阅读模式

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

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

x
这几天想学学python,画了一个WRF小时降水的图,不同时次的结果存储在同一个PDF文件中。
总体感觉画图不如NCL方便,lambert投影的时候无法添加经纬度坐标,也可能是我刚学,没有弄明白?
代码如下,给初学者大家一起学习交流:
  1. from netCDF4 import Dataset
  2. import xarray as xr
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. import cartopy.crs as ccrs
  6. from matplotlib.cm import get_cmap
  7. import matplotlib.colors as colors
  8. from cartopy.io.shapereader import Reader
  9. import cartopy.feature as cfe
  10. import cmaps
  11. from matplotlib.backends.backend_pdf import PdfPages
  12. from wrf import (get_cartopy, latlon_coords, to_np, cartopy_xlim, cartopy_ylim,
  13.                  getvar, ALL_TIMES)
  14.                  
  15. f = Dataset('wrfout_d01')
  16. # rainc = np.array(f.variables['RAINC'][:])
  17. # rainnc = np.array(f.variables['RAINNC'][:])

  18. rainc = getvar(f, 'RAINC', timeidx=ALL_TIMES)
  19. rainnc = getvar(f, 'RAINNC', timeidx=ALL_TIMES)

  20. # f = xr.open_dataset('wrfout_d01')
  21. # rainc = f['RAINC']
  22. # rainnc = f['RAINNC']

  23. tot = rainc.values + rainnc.values
  24. wrf_time = f.variables['Times']

  25. # tot = rainc + rainnc
  26. dim_tot = tot.shape
  27. h1prep = tot[2:dim_tot[0]:2,:,:] - tot[0:dim_tot[0]-2:2,:,:]

  28. # lats = f['XLAT'].values[0]
  29. # lons = f['XLONG'].values[0]

  30. lats = f.variables['XLAT'][0]
  31. lons = f.variables['XLONG'][0]

  32. # lats, lons = latlon_coords(rainc)
  33. cart_proj = get_cartopy(rainc)
  34. # print(cart_proj)

  35. levels = [0.1,0.5,1.,2.,3.,4.,5.,6.,8.,10.,20.,40]
  36. norm = colors.BoundaryNorm(boundaries=np.array(levels), ncolors=len(levels)-1)

  37. shp_path = '/Users/james/Documents/GitHub/py_china_shp/'
  38. reader = Reader(shp_path  +  'Province_9/Province_9.shp')
  39. provinces = cfe.ShapelyFeature(reader.geometries(), ccrs.PlateCarree(), edgecolor='k', facecolor='none')


  40. with PdfPages('multipage_pdf.pdf') as pdf:
  41.     for i in range(3):
  42.         fig = plt.figure(figsize=(14,8.5))
  43.         ax = fig.add_subplot(111, projection=cart_proj)
  44.         print(ax)   

  45.         ax.add_feature(provinces, linewidth=0.6)
  46.         ax.coastlines('50m', linewidth=0.8)
  47.    
  48.         pcm = ax.contourf(lons, lats, h1prep[i], levels, norm=norm,
  49.                      transform=ccrs.PlateCarree(), extend='both',
  50.                      cmap=cmaps.cmorph[1:])
  51.         #pcm.cmap.set_over('white')

  52.         pcm.cmap.set_under(cmaps.cmorph.colors[0])  

  53.         # Set the map bounds
  54.         # 两种方式设定画图范围
  55.         # 方式1
  56.         # xs, ys, _ = cart_proj.transform_points(ccrs.PlateCarree(),np.array([lons[0,0],lons[-1,-1]]),np.array([lats[0,0],lats[-1,-1]])).T
  57.         # xlimits = xs.tolist()
  58.         # ylimits = ys.tolist()
  59.         # ax.set_xlim(xlimits)
  60.         # ax.set_ylim(ylimits)
  61.         # print(xlimits)
  62.         # print(ylimits)
  63.         # 方式2
  64.         # ax.set_xlim(cartopy_xlim(rainc))
  65.         # ax.set_ylim(cartopy_ylim(rainc))  

  66.         ax.set_title("WRF Prepcipitation {}".format(str(wrf_time[i],'utf-8')))
  67.         ax.gridlines(linewidth=0.5, color='gray', linestyle='--')   

  68.         # plt.colorbar(pcm, ax=ax, ticks=levels, extendfrac='auto',
  69.         #              aspect=20, extendrect=True, format='%3.1f', drawedges=True, shrink=.7)
  70.         plt.colorbar(pcm, ax=ax, ticks=levels, extendfrac='auto',
  71.                      aspect=18, format='%3.1f', shrink=.95)
  72.         pdf.savefig()  # saves the current figure into a pdf page
  73.         plt.close()

  74.     # plt.suptitle('Figure title')
  75.     # # shrink 调整colorbar大小   

  76.     # plt.show()
复制代码
以下是画出来的图:

WX20200424-114535@2x.png
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2020-4-28 17:19:02 | 显示全部楼层
lon_formatter = cticker.LongitudeFormatter()
lat_formatter = cticker.LatitudeFormatter()
密码修改失败请联系微信:mofangbao
回复 支持 1 反对 0

使用道具 举报

新浪微博达人勋

发表于 2020-4-30 16:57:22 | 显示全部楼层
楼上正解!
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2020-5-7 10:58:29 | 显示全部楼层
暗藏 发表于 2020-4-28 17:19
lon_formatter = cticker.LongitudeFormatter()
lat_formatter = cticker.LatitudeFormatter()

谢谢,我之前用的cartopy0.17版本,更新到0.18版本以后就可以画这个经纬度坐标了。
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2020-5-9 18:04:52 | 显示全部楼层
本帖最后由 蝶与鲸 于 2020-5-9 20:41 编辑

我也更新至18.0,使用兰伯特投影,还是会报错诶。TypeError: Cannot label LambertConformal gridlines. Only PlateCarree gridlines are currently supported.
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2020-5-10 13:36:32 | 显示全部楼层
蝶与鲸 发表于 2020-5-9 18:04
我也更新至18.0,使用兰伯特投影,还是会报错诶。TypeError: Cannot label LambertConformal gridlines. On ...

我也是  不过我的报错是:
    raise RuntimeError('Cannot handle non-rectangular coordinate '
RuntimeError: Cannot handle non-rectangular coordinate systems.
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2020-5-11 11:04:33 | 显示全部楼层
风暴之灵 发表于 2020-5-7 10:58
谢谢,我之前用的cartopy0.17版本,更新到0.18版本以后就可以画这个经纬度坐标了。

这个不清楚了,我更新了之后就不会报这个错误了。。
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2020-5-20 19:11:23 | 显示全部楼层
风暴之灵 发表于 2020-5-11 11:04
这个不清楚了,我更新了之后就不会报这个错误了。。

请问,能不能把添加坐标的代码发一下
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2020-5-22 15:53:30 | 显示全部楼层
青山见我应如是 发表于 2020-5-20 19:11
请问,能不能把添加坐标的代码发一下

lon_formatter = cticker.LongitudeFormatter()
lat_formatter = cticker.LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2020-5-25 15:51:28 | 显示全部楼层
hanf 发表于 2020-5-22 15:53
lon_formatter = cticker.LongitudeFormatter()
lat_formatter = cticker.LatitudeFormatter()
ax.xaxi ...

如果cticker.LongitudeFormatter()指的是from cartopy.mpl.ticker import LongitudeFormatter,LatitudeFormatter的话,我想问一下 ax.set_xticks()语句该怎么写 ,只写lon_formatter = cticker.LongitudeFormatter()lat_formatter = cticker.LatitudeFormatter()ax.xaxis.set_major_formatter(lon_formatter)ax.yaxis.set_major_formatter(lat_formatter)不显示坐标啊,但是加上ax.set_yticks(np.linspace(box[2], box[3],5), crs=proj )就报错
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

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