爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 39731|回复: 25

[经验总结] matplotlib自定义colormap

[复制链接]

新浪微博达人勋

发表于 2016-2-27 20:05:34 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 Lighting 于 2016-9-23 21:56 编辑

          最近使用python处理WRF输出的nc文件,在出图的时候由于自带的colormap无法满足需要,自己就查看了matplotlib的官方文档,又搜索了网上的一些资料,就试着自定义了colormap。便把一些方法和感想记录下来,分享一下,当然主要还是怕自己忘了~~

===============================================================
           本帖主要就介绍一下matplotlib中自定义colormap的一些命令,以及制作colormap的一些方法。
1) matplotlib.Colors.LinearSegmentedColormap (name,segmentdata,N=256,gamma=1.0)
       colormap对象以线性分割的数据列表为基础,数据列表是由原色三元组进行线性插值产生,为[0 1]之间的值。
       其中segmentdata是一个由red,blue,green词条构成的词典,每一个词条都由 x,y0,y1三个值构成,参数alpha为可选项。词条中的三个值的含义为:x 表示在colorbar中的位置,即colorbar的长度为1,因此 x 的值在[0 1]之间,且只能单调变化; y0,y1为表示颜色的值,通常为相同的值,如果取值不同时,对colormap的变化更有帮助。y0表示为 x 左边的颜色值,y1表示为 x 右边的颜色值。
       下面举个例子:         
cdict = {'red':   [(0.0,  0.0, 0.0),
                            (0.5,  1.0, 1.0),
                            (1.0,  1.0, 1.0)],
             'green': [(0.0,  0.0, 0.0),
                            (0.25, 0.0, 0.0),
                            (0.75, 1.0, 1.0),
                            (1.0,  1.0, 1.0)],         
               'blue':  [(0.0,  0.0, 0.0),
                             (0.5,  0.0, 0.0),
                             (1.0,  1.0, 1.0)]}
上述词典中 red 数据表示把colorbar中red分为两部分,[0 0.5]和[0.5 1],绿色分为三部分,即在[0 0.25]之间green为0,[0.25,0.75]之间
green为1,[0.75,1]之间green为1,蓝色同理。
    gamma值用于调节colormap底部和顶部的亮度。
    因为每一段的颜色都是在y0和y1之间进行插值所得,因此第一行的y0和最后一行的y1是不会用到的。
2) matplotlib.colors.ListedColormap(colors,name='from_list',N=None)
3) matplotlib.cm.get_cmap(name=None,lut=None)
4)  matplotlib.cm.register_cmap(name=None,cmap=None,data=None,lut=NOne)
    以上几个命令不再一一赘述,更详细的信息可以点我

==========================================================================
    以下是一些创建colormap的方法:
1) 使用LinearSegmentedColormap命令
   
  1. import matplotlib.colors as col
  2. cdict = {'red': ((0.0, 0.0, 0.0),
  3.                           (0.3, 0.5, 0.5),
  4.                           (0.6, 0.7, 0.7),
  5.                           (0.9, 0.8, 0.8),
  6.                           (1.0, 0.8, 0.8)),
  7.             'green': ((0.0, 0.0, 0.0),
  8.                            (0.3, 0.8, 0.8),
  9.                            (0.6, 0.7, 0.7),
  10.                            (0.9, 0.0, 0.0),
  11.                            (1.0, 0.7, 0.7)),
  12.                       'blue': ((0.0, 1.0, 1.0),
  13.                                    (0.3, 1.0, 1.0),
  14.                                   (0.6, 0.0, 0.0),
  15.                                   (0.9, 0.0, 0.0),
  16.                            (1.0, 1.0, 1.0))}
  17. cmap1 = col.LinearSegmentedColormap('my_colormap',cdict,N=256,gamma=0.75)  
  18. # my_colormap可以自定义,如果没有cmap1,下面的cmap1可以换位my_colormap,但是为字符串格式
  19. # gamma项 一般可以省略
  20.     cm.register_cmap(name='own1', cmap=cmap1)   # 进行‘注册’,使get_cmap命令能检索到该cmap

  21. <span id="kM0.04844997560317399">2) 使用from_list方法
  22. </span><div class="blockcode"><blockquote>import matplotlib.colors as col
  23. startcolor = '#586323'
  24. midcolor = '#fcffc9'
  25. endcolor = '#bd2309'
  26. cmap2 = col.LinearSegmentedColormap.from_list('own2',[startcolor,midcolor,endcolor])
  27. cm.register_cmap(cmap=cmap2)
复制代码
3) 使用ListedColormap命令
  1. import matplotlib.colors as col
  2. cpool = [ '#bd2309', '#bbb12d', '#1480fa', '#14fa2f', '#000000',
  3.               '#faf214', '#2edfea', '#ea2ec4', '#ea2e40', '#cdcdcd',
  4.               '#577a4d', '#2e46c0', '#f59422', '#219774', '#8086d9' ]
  5. cmap3 = col.ListedColormap(cpool[0:10], 'indexed')
  6. # 注意:cpool中有15个颜色,但是只使用了10个,其余的会被忽略
  7. # 具体可查阅matplotlib官方文档中对ListedColormap的说明
  8. cm.register_cmap(cmap=cmap3)
复制代码
       除了使用matplotlib自定义colormap外,还有一个独立的colormap库可用于创建colormap,这个我没有仔细研究,大概看了一下,用法不难,有兴趣的可以看一下 点我查看
         
========================================
        最后上我自己处理nc文件并自定义colormap的代码
  1. import netCDF4 as nc
  2. import matplotlib.pyplot as plt
  3. from mpl_toolkits.basemap import Basemap
  4. import numpy as np

  5. filepath   = '/run/media/root/*WRF/-5/s/wrfout_d02_2014-09-28_12_00_00'
  6. data       = nc.Dataset(filepath,'r')

  7. var        = 'REFL_10CM'
  8. dbz        = data.variables[var][:]
  9. dbzsize    = np.shape(data.variables[var])
  10. timelen    = dbzsize[0]
  11. heightlen  = dbzsize[1]
  12. latlen     = dbzsize[2]
  13. lonlen     = dbzsize[3]
  14. print(dbzsize)

  15. lats  = 30;  late  = 35;
  16. lons  = 114; lone  = 120;
  17. m = Basemap(projection='cyl',llcrnrlat=lats,urcrnrlat=late,llcrnrlon=lons,urcrnrlon=lone,resolution='i')
  18. m.drawparallels(np.arange(lats,late+1,1.),labels = [1,0,0,0],fontsize=15,linewidth = 0. )
  19. # set linewidth = 0 to turn off longitude and latitude dash line
  20. m.drawmeridians(np.arange(lons,lone+2,2.),labels = [0,0,0,1],fontsize=15,linewidth = 0.)
  21. m.drawcoastlines()
  22. m.drawcountries()
  23. #m.drawlsmask()
  24. lon,lat  = m.makegrid(lonlen,latlen)
  25. print(np.shape(lon))
  26. x,y = m(lon,lat)
  27. clevs = np.arange(0,70,10)
  28. cdict = {'red'  : [(0.,0,1),
  29.                    (0.15,1.,1.),
  30.                    (0.3,0.85,0.85),
  31.                    (0.45,0.7,0.7),
  32.                    (0.6,0.55,0.55),
  33.                    (0.75,0.4,0.4),
  34.                    (0.9,0,1),
  35.                    (1.,1.,0.)],
  36.          'green' : [(0.,0,1),
  37.                    (0.15,1.,1.),
  38.                    (0.3,0.85,0.85),
  39.                    (0.45,0.7,0.7),
  40.                    (0.6,0.55,0.55),
  41.                    (0.75,0.4,0.4),
  42.                    (0.9,1.,1.),
  43.                    (1.,1.,1.)],
  44.          'blue'  : [(0.,0,1),
  45.                    (0.15,1.,1.),
  46.                    (0.3,0.85,0.85),
  47.                    (0.45,0.7,0.7),
  48.                    (0.6,0.55,0.55),
  49.                    (0.75,0.4,0.4),
  50.                    (0.9,1,1.),
  51.                    (1.,1.,1.)]}
  52. my_cmap = colors.LinearSegmentedColormap(name='dbzcmap',segmentdata = cdict,N=256)
  53. #cm.register_cmap(name = 'dbzcmap',data = cdict,lut = 128)
  54. # 如果把上述语句取消注释,把LinearSegmentedColormap语句行注释掉,也可定义colormap
  55. # 但是下面语句中的cmap=my_cmap应改为 cmap = 'dbzcmap'
  56. ref  = m.contourf(lon,lat,dbz[29,29,:,:],clevs,alpha = 1,cmap= my_cmap)#plt.cm.Greys)  
  57. # alpha 表示透明度
  58. cbar = m.colorbar(ref)
  59. cbar.set_label('dBZ')
  60. axes = plt.gca()
  61. plt.grid(False)

  62. plt.title('Reflectivity plot for WRF_ARW',size = 20)
  63. plt.savefig('dbz')
  64. plt.show()
复制代码

      出图效果改天上传。如果大家有什么疑问,欢迎和我一起探讨!

=========================================================
       出图效果见图片(配色不太好)。
       自定义colormap时,个人还是感觉还是利用下面的方法好一些。
  1. cdict = ['#FFFFFF','#c3e3f4','#4552a2','#b6dd79','#8fc824',
  2.          '#77bd29','#65b430','#e58814','#ce2823','#c41d24',
  3.          '#9a1a1f','#731417','#000000']
  4. my_cmap = colors.ListedColormap(cdict,'indexed')
  5. cm.register_cmap(name = 'dbzcmap',data = cdict,lut = 128)
复制代码
      对于初学者来说,比之前提到的方法更容易控制颜色。

dbz.png
sctot.png
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-3-17 23:52:54 | 显示全部楼层
赞一个,顺便推荐一个包:brewer2mpl,里面好多漂亮的colormap
密码修改失败请联系微信:mofangbao
回复 支持 2 反对 0

使用道具 举报

新浪微博达人勋

发表于 2016-2-27 20:19:21 | 显示全部楼层
不错啊,学习学习
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-3-22 09:39:24 | 显示全部楼层
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-3-22 14:41:27 | 显示全部楼层
{:eb511:}
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

发表于 2016-4-1 20:39:23 | 显示全部楼层
不错~
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-5-8 20:46:52 | 显示全部楼层
高大上啊&#128561;
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-5-17 09:14:00 | 显示全部楼层
{:eb511:}
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

发表于 2016-7-23 16:04:35 | 显示全部楼层
及时雨  正在用
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-8-9 11:38:46 | 显示全部楼层
楼主,我想问下定义了颜色字典,再怎么定义cmap呢?{0.:'w', 1.:'#A6F28F', 1.5:'#3DBA3D', 7.:'#61B8FF', 15.:'#0000E1', 40.:'#FA00FA', 50.:'#800040'}
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

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

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

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