爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 7168|回复: 9

[求助] colorbar 非均匀色标

[复制链接]

新浪微博达人勋

发表于 2022-1-25 11:54:29 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 XiaoMaFenJu 于 2022-1-28 17:03 编辑

问题描述:
下图是我想要得到的结果,特点是数值非均匀但间距相等,也就是colorbar密度不同。
1.png



目前达到的结果为下图

2.png

代码如下

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. import matplotlib as mpl
  4. #数据读取
  5. data1 = np.loadtxt("./data/test.asc", skiprows=6)
  6. #绘图,透明度50%,下限值0
  7. img1 = plt.imshow(data1,alpha=0.5,vmin = 0,cmap = mpl.cm.get_cmap("plasma").copy())
  8. #缺省值设置无色
  9. img1.cmap.set_under(alpha = 0)

  10. levels = [0,0.5,1,10,100,500,1000,2000,5000,10000]
  11. h = plt.colorbar(ticks=levels,spacing = 'uniform')
  12. plt.show()
复制代码

实在不知道咋办了,请各位大佬指点!
我目前还有两种想法,一种是自定义colormap,一种是改坐标轴ticks,但是看了许久还是没看明白,😔

====================================2022.01.28========================================

更新!!!问题解决!
也非常感谢评论区的各位大佬,这两天也是在自己摸索(摸鱼),找官方文档和茫茫的百度,选定的是 mpl.colors.BoundaryNorm ,但还是有点差距,还是密度问题没有解决,但看到评论区大佬也有用这个方法,和我当时找到的BoundaryNorm大体是运用一样的,那说明这个应该是没有错的,那问题应该在别的地方。
正好前时间在找资料的时候找到一个“炸鸡人博客”,链接就不放了 ps:不让放;) ,有很详细的colormap和colorbar的讲解(我觉得这篇博客很nice,比官方文档看起来还舒服),当时我着重在BoundaryNorm,于是翻看其他部分,找到下面这句话:
  1. 对于画马赛克图的 pcolor、pcolormesh 和 imshow 函数,我们在实际使用中并不需要手动进行数据的归一化和颜色索引,只需在调用函数时通过 cmap 和 norm 参数把 colormap 和归一化的类传入即可,绘图函数会自动计算数据和颜色的对应关系。cmap 默认为 viridis,norm 默认为无参数的 Normalize。
复制代码
但是我之前是试过的,camp可以传入,但是norm会报错,这时我又去看那篇博客,发现
  1. # 若在pcolormesh中给定了norm,就不能再指定vmin和vmax了.
复制代码
问题可以说解决了!删掉imshow()中的vmin和vmax,转而传入norm就没问题了!
很感谢评论区的各位大佬!
完整代码我会附在下面!
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. import matplotlib as mpl
  4. #数据读取
  5. data = np.loadtxt("./data.asc", skiprows=6)
  6. #colorbar设置
  7. cmap = mpl.cm.jet
  8. bins = [0, 0.5, 1, 10, 50, 100, 500, 1000, 2000, 5000]
  9. nbin = len(bins) - 1
  10. npt = cmap.N // nbin
  11. segments = []
  12. for i in range(nbin):
  13.     segment = np.linspace(bins[i], bins[i + 1], npt)
  14.     if i < nbin - 1:
  15.         segment = segment[:-1]
  16.     segments.append(segment)
  17. segments = np.concatenate(segments)
  18. norm = mpl.colors.BoundaryNorm(segments, cmap.N)
  19. #绘图,透明度50%,下限值0
  20. img1 = plt.imshow(data,alpha=0.5,norm = norm,cmap = cmap.copy())
  21. #缺省值设置无色
  22. img1.cmap.set_under(alpha = 0)
  23. #colorbar
  24. h = plt.colorbar()
  25. h.set_ticks(bins)
  26. h.set_ticklabels(bins)
  27. #本地保存
  28. #plt.savefig('test5',dpi = 1600)
  29. #图片输出
  30. plt.show()
复制代码
输出结果如下:
123.png
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2022-1-25 19:56:34 | 显示全部楼层
本帖最后由 灭火器 于 2022-1-25 19:59 编辑

一个迂回的方法
  1. cmap = cm.jet
  2. bins = [0, 0.5, 1, 10, 50, 100, 500, 1000, 2000, 5000]
  3. nbin = len(bins) - 1
  4. npt = cmap.N // nbin
  5. segments = []
  6. for i in range(nbin):
  7.     segment = np.linspace(bins[i], bins[i + 1], npt)
  8.     if i < nbin - 1:
  9.         segment = segment[:-1]
  10.     segments.append(segment)
  11. segments = np.concatenate(segments)
  12. norm = mcolors.BoundaryNorm(segments, cmap.N)
复制代码
然后设置刻度
  1. cbar.set_ticks(bins)
  2. cbar.set_ticklabels(bins)
复制代码
效果如图
test.png

密码修改失败请联系微信:mofangbao
回复 支持 1 反对 0

使用道具 举报

新浪微博达人勋

发表于 2022-1-25 12:40:18 | 显示全部楼层
我有一个笨的办法,你把你数据放缩一下,在画图,最后改colorbar的string
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2022-1-25 13:03:19 | 显示全部楼层
同上!同上!同上!同上!同上!同上!
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2022-1-25 13:23:16 | 显示全部楼层
lightmoon 发表于 2022-1-25 12:40
我有一个笨的办法,你把你数据放缩一下,在画图,最后改colorbar的string

倒是个方法,实在不行也就得用这个
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2022-1-25 15:14:26 | 显示全部楼层
plt.contourf(x,y,data,levels,cmap)
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2022-1-25 15:49:23 | 显示全部楼层
根据以往的经验,这个colorbar的刻度很难调;
一种方法是自己画一个色条,不用colorbar这个api,画矩形组合,每个组合填色,然后自定义坐标轴刻度
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2022-1-28 16:19:06 | 显示全部楼层
灭火器 发表于 2022-1-25 19:56
一个迂回的方法然后设置刻度
效果如图

很棒了,我也是找到BoundaryNorm,但是一直还是差点,感谢感谢
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2022-1-28 17:06:16 | 显示全部楼层
失落的积雨云 发表于 2022-1-25 15:14
plt.contourf(x,y,data,levels,cmap)

这个我考虑过,我的数据还要再去创建x,y,所以就没优先考虑
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2022-1-28 23:02:07 | 显示全部楼层
XiaoMaFenJu 发表于 2022-1-28 16:19
很棒了,我也是找到BoundaryNorm,但是一直还是差点,感谢感谢

那个博客就是我写的啊,vmin和vmax的地方偷懒没讲清楚。这两个参数就是线性的Normalize里的参数,contourf和pcolor里也有是为了方便你使用,以省略掉norm参数。如果你要使用其它类型的归一化,这两个参数就没用了,也不应该给出。
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

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