相关文章推荐
有胆有识的人字拖  ·  matplotlib ...·  3 天前    · 
着急的野马  ·  matplotlib画3D图修改X,Y,Z, ...·  3 天前    · 
踏实的烤地瓜  ·  python ...·  3 天前    · 
爱逃课的墨镜  ·  在OpenResty中使用lua-zlib的 ...·  1 年前    · 
聪明的课本  ·  开源软件在地图数据处理中的应用 - 知乎·  2 年前    · 
帅气的青蛙  ·  MFC之使用 Windows 标准控件 - ...·  2 年前    · 
微笑的煎饼果子  ·  数亿数据MySQL撑不住,无缝迁移到Mong ...·  2 年前    · 
Code  ›  matplotlib 合理设置colorbar和子图的对应关系_plt.colorbar与子图的距离
random axes norm matplotlib
https://blog.csdn.net/weixin_43718675/article/details/102639611
有胆有识的人字拖
3 天前
    • matplotlib 合理设置colorbar和子图的对应关系
      • 1. 介绍
      • 2 plt.contourf ()
        • 2.1 错误示范
        • 2.2 使用 norm实现颜色和数值之间的对应关系
        • 2.3 只显示最后一个的colorbar
        • 2.4 使用 levels 参数设置
      • 3. 使用plt.imshow()
      • 4 单独设置colorbar
        • 4.1 方式一
        • 4.2 方式二
        • 4.3 问题
        • 4.4 解决方法1:plt.contourf()
        • 4.5 解决办法2:plt.imshow()

        1. 介绍

        在有些情况下,需要画同一个变量不同时刻的等值面图。考虑到不同时刻的数值有大小差异,因而生成的图的colorbar的标签范围也是不一样的。为了方便比较,最好多个时刻共享一个colorbar,方便比较。下面会依次使用 plt.contourf() 和 plt.imshow()函数进行画图介绍。

        2 plt.contourf ()

        2.1 错误示范
        import numpy as np
        import matplotlib.pyplot as plt
        import matplotlib
        #生成一定整数范围内的随机数
        a1 = np.random.randint(1,10,size=(10,10))
        a2 = np.random.randint(1,13,size=(10,10))
        a3 = np.random.randint(1,16,size=(10,10))
        fig = plt.figure(figsize = (22,6))
        plt.subplot(1,3,1)
        h1 = plt.contourf(a1,cmap = plt.cm.coolwarm)
        c1 = plt.colorbar(h1)
        plt.subplot(1,3,2)
        h2 = plt.contourf(a2,cmap = plt.cm.coolwarm)
        c2 = plt.colorbar(h2)
        plt.subplot(1,3,3)
        h3 = plt.contourf(a3,cmap = plt.cm.coolwarm)
        c3 = plt.colorbar(h3) 
        plt.show()
        

        在这里插入图片描述
        如上图,每个图上的相同的颜色表示的数值不一样,不方便比较;

        2.2 使用 norm实现颜色和数值之间的对应关系
        a1 = np.random.randint(1,10,size=(10,10))
        a2 = np.random.randint(1,13,size=(10,10))
        a3 = np.random.randint(1,16,size=(10,10))
        fig = plt.figure(figsize = (22,6))
        #将颜色映射到 vmin~vmax 之间
        norm = matplotlib.colors.Normalize(vmin=0, vmax=15)
        plt.subplot(1,3,1)
        h1 = plt.contourf(a1,cmap = plt.cm.coolwarm,norm = norm)
        c1 = plt.colorbar(h1)
        plt.subplot(1,3,2)
        h2 = plt.contourf(a2,cmap = plt.cm.coolwarm,norm = norm)
        c2 = plt.colorbar(h2)
        plt.subplot(1,3,3)
        h3 = plt.contourf(a3,cmap = plt.cm.coolwarm,norm = norm)
        c3 = plt.colorbar(h3)
        plt.show()
        

        在这里插入图片描述
        如上图,可以实现相同数值大小对应相同的颜色;

        但是这样还是不太好看。最好是能够 每个子图的 colorbar的范围都一样(即从0-15);

        2.3 只显示最后一个的colorbar

        那有同学想,是否可以只显示最后一个子图的colorbar,作为全局colorbar呢;这个当然也是可以的。

        但是会带来一个问题,由于每个子图的大小(无论是否包含colorbar)是一样的,会使得图形大小看起来不一样,很不美观;

        2.4 使用 levels 参数设置
        a1 = np.random.randint(1,10,size=(10,10))
        a2 = np.random.randint(1,13,size=(10,10))
        a3 = np.random.randint(1,16,size=(10,10))
        fig = plt.figure(figsize = (22,6))
        # norm = matplotlib.colors.Normalize(vmin=0, vmax=15)
        #设置固定显示的colorbar刻度
        levels = np.arange(0,17,2)
        plt.subplot(1,3,1)
        h1 = plt.contourf(a1,cmap = plt.cm.coolwarm,levels = levels)
        c1 = plt.colorbar(h1)
        plt.subplot(1,3,2)
        h2 = plt.contourf(a2,cmap = plt.cm.coolwarm,levels = levels)
        c2 = plt.colorbar(h2)
        plt.subplot(1,3,
        
        
        
        
            
        3)
        h3 = plt.contourf(a3,cmap = plt.cm.coolwarm,levels = levels)
        c3 = plt.colorbar(h3)
        plt.show()
        

        3. 使用plt.imshow()

        上面虽然设置了 norm,但是使用plt.contourf还是达不到我们的要求。链接3 给了我们一个示例,使用plt.imshow() + norm可以解决这个问题。按照他的思路,我们重复上面的试验。

        import numpy as np
        import matplotlib.pyplot as plt
        import matplotlib
        # matplotlib.rcParams['xtick.direction'] = 'out'
        # matplotlib.rcParams['ytick.direction'] = 'out'
        a1 = np.random.randint(1,10,size=(10,10))
        a2 = np.random.randint(1,13,size=(10,10))
        a3 = np.random.randint(1,16,size=(10,10))
        fig = plt.figure(figsize = (22,6),dpi=72, facecolor="white")
        #将横纵坐标都映射到(0,1)的范围内
        extent=(0,1,0,1)
        vmin=0
        vmax=15
        #将颜色映射到 vmin~vmax 之间
        norm = matplotlib.colors.Normalize(vmin=0, vmax=15)
        ax1 = plt.subplot(1,3,1)
        ax1.cla()
        h1 = plt.imshow(a1,extent = extent,origin='lower',cmap = plt.cm.coolwarm,norm = norm)
        c1 = plt.colorbar(h1)
        plt.subplot(1,3,2)
        h2 = plt.imshow(a2,extent = extent,origin='lower',cmap = plt.cm.coolwarm,norm = norm)
        c2 = plt.colorbar(h2)
        plt.subplot(1,3,3)
        h3 = plt.imshow(a3,extent = extent,origin='lower',cmap = plt.cm.coolwarm,norm = norm)
        c3 = plt.colorbar(h3)
        font = {'family' : 'serif',
                'color'  : 'darkred',
                'weight' : 'normal',
                'size'   : 16,
        c3.set_label('$T_B(K)$',fontdict=font)
        c3.set_ticks(np.arange(vmin,vmax,2))
        c3.set_ticklabels(np.arange(vmin,vmax,2))
        plt.show()
        

        如上图,虽然使用plt.imshow可以解决这个问题,但是用带来了一些新问题:

        • 在画子图的时候,colorbar的长度和子图的长度不一致;在单独画一个图的时候,并不存在这样的问题
        • plt.imshow()是逐像素画图的,相比plt.contourf,分辨率很低,并不适合科研上的等值线作图。

        4 单独设置colorbar

        import numpy as np
        import matplotlib.pyplot as plt
        import matplotlib
        a1 = np.random.randint(1,10,size=(10,10))
        a2 = np.random.randint(1,13,size=(10,10))
        a3 = np.random.randint(1,16,size=(10,10))
        #也可以通过这样 levels 进行设置
        #h = plt.contourf(a1,levels = [0,1,2,3,4,5,6,7,8,9,10], cmap = plt.cm.coolwarm)
        fig = plt.figure(figsize = (22,6))
        norm = matplotlib.colors.Normalize(vmin=0, vmax=15)
        plt.subplot(1,3,1)
        h1 = plt.contourf(a1,cmap = plt.cm.coolwarm,norm = norm)
        # c1 = plt.colorbar(h1)
        plt.subplot(1,3,2)
        h2 = plt.contourf(a2,cmap = plt.cm.coolwarm,norm = norm)
        # c2 = plt.colorbar(h2)
        plt.subplot(1,3,3)
        h3 = plt.contourf(a3,cmap = plt.cm.coolwarm,norm = norm)
        # c3 = plt.colorbar(h3)
        # c3.set_clim(vmax = 15)
        #前面三个子图的总宽度 为 全部宽度的 0.9;剩下的0.1用来放置colorbar
        fig.subplots_adjust(right=0.9)
        #colorbar 左 下 宽 高 
        l = 0.92
        b = 0.12
        w = 0.015
        h = 1 - 2*b 
        #对应 l,b,w,h;设置colorbar位置;
        rect = [l,b,w,h] 
        cbar_ax = fig.add_axes(rect) 
        cb = plt.colorbar(h3, cax=cbar_ax)
        #设置colorbar标签字体等
        cb.ax.tick_params(labelsize=16)  #设置色标刻度字体大小。
        font = {'family' : 'serif',
        #       'color'  : 'darkred',
            'color'  : 'black',
            'weight' : 'normal',
            'size'   : 16,
        cb.set_label('T' ,fontdict=font) #设置colorbar的标签字体及其大小
        plt.show()
        

        在这里插入图片描述
        如上,是不是很漂亮了。后续适当做一些 坐标、字体等的基本设置,就完成了一张科研图的绘制!

        4.1 方式一
        import numpy as np
        import matplotlib.pyplot as plt
        import matplotlib
        a1 = np.random.randint(1,10,size=(10,10))
        a2 = np.random.randint(1,13,size=(10,10))
        a3 = np.random.randint(1,16,size=(10,10))
        #也可以通过这样 levels 进行设置
        #h = plt.contourf(a1,levels = [0,1,2,3,4,5,6,7,8,9,10], cmap = plt.cm.coolwarm)
        fig = plt.figure(figsize = (22,6))
        norm = matplotlib.colors.Normalize(vmin=0, vmax=15)
        plt.subplot(1,3,1)
        h1 = plt.contourf(a1,cmap = plt.cm.coolwarm,norm = norm)
        # c1 = plt.colorbar(h1)
        plt.subplot(1,3,2)
        h2 = plt.contourf(a2,cmap = plt.cm.coolwarm,norm = norm)
        # c2 = plt.colorbar(h2)
        plt.subplot(1,3,3)
        h3 = plt.contourf(a3,cmap = plt.cm.coolwarm,norm = norm)
        # c3 = plt.colorbar(h3)
        # c3.set_clim(vmax = 15)
        #前面三个子图的总宽度 为 全部宽度的 0.9;剩下的0.1用来放置colorbar
        fig.subplots_adjust(right=0.9)
        #colorbar 左 下 宽 高 
        l = 0.92
        b = 0.12
        w = 0.015
        h = 1 - 2*b 
        #对应 l,b,w,h;设置colorbar位置;
        rect = [l,b,w,h] 
        cbar_ax = fig.add_axes(rect) 
        cb = plt.colorbar(h3, cax=cbar_ax)
        #设置colorbar标签字体等
        
        
        
        
            
        
        cb.ax.tick_params(labelsize=16)  #设置色标刻度字体大小。
        font = {'family' : 'serif',
        #       'color'  : 'darkred',
            'color'  : 'black',
            'weight' : 'normal',
            'size'   : 16,
        cb.set_label('T' ,fontdict=font) #设置colorbar的标签字体及其大小
        plt.show()
        

        在这里插入图片描述
        如上,是不是很漂亮了。后续适当做一些 坐标、字体等的基本设置,就完成了一张科研图的绘制!

        4.2 方式二
        import numpy as np
        import matplotlib.pyplot as plt
        import matplotlib
        #设置子图个数 和 整个图片的大小
        fig, axes = plt.subplots(nrows=2, ncols=2,figsize = (12,10))
        a_list = [5,10,15,20]
        #设置colorbar的范围
        vmin = 0
        vmax = 20
        norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
        for a,ax in zip(a_list,axes.flat):
            #设置每个子图
            data = np.random.randint(0,a,size = (20,20))
            im = ax.contourf(data,norm = norm)
        #fig 的位置为[0,1],设置前面4个子图的占的位置为[0,0.8]
        fig.subplots_adjust(right=0.8)
        #在原fig上添加一个子图句柄为cbar_ax, 设置其位置为[0.85,0.15,0.05,0.7]
        #colorbar 左 下 宽 高 
        l = 0.85
        b = 0.12
        w = 0.05
        h = 1 - 2*b 
        #对应 l,b,w,h;设置colorbar位置;
        rect = [l,b,w,h] 
        cbar_ax = fig.add_axes(rect)
        cb = fig.colorbar(im, cax = cbar_ax) 
        #设置colorbar标签字体等
        cb.ax.tick_params(labelsize=16)  #设置色标刻度字体大小。
        font = {'family' : 'serif',
        #       'color'  : 'darkred',
            'color'  : 'black',
            'weight' : 'normal',
            'size'   : 16,
        cb.set_label('T' ,fontdict=font) #设置colorbar的标签字体及其大小
        plt.show()
        
        4.3 问题

        上述两种方式都存在一个潜在的问题。

        ​ 在添加colorbar的时,是使用最后一个子图的所在的数值范围。我们来看几种情况。

        • 情况一:

          norm = [5,20], 对应colorbar上 5以下颜色一致。

        • 情况二:

          最后一张子图的数值范围为 [0,15),colorbar范围只能在15以内。

        最后一张子图的数据范围决定了colorbar上显示的刻度的范围。

        norm范围决定了colorbar颜色变化范围。

        4.4 解决方法1:plt.contourf()

        为了保证colorbar能覆盖所有子图的范围,应该使得 norm范围与设置colorbar时对应的子图im 的数值范围一致,并且所有子图的数值范围应该都在norm范围之内。

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bI7GRXmn-1582701105492)(matplotlib 合理设置colorbar和子图的对应关系.assets/image-20200226135804785.png)]

        因此有一个蠢办法:

        • 即另外建一个fig2 , 这个fig2对应的数据范围包括fig1的数据范围。

          import numpy as np
          import matplotlib.pyplot as plt
          import matplotlib
          #设置子图个数 和 整个图片的大小
          fig1, axes = plt.subplots(nrows=2, ncols=2,figsize = (10,8))
          a_list = [5,10,20,15]
          #设置colorbar的范围
          vmin = 0
          vmax = 20
          norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
          for a,ax in zip(a_list,axes.flat):
              #设置每个子图的数据范围
              data = np.random.randint(0,a,size = (20,20))
              im = ax.contourf(data,norm = norm)
          #fig1 的位置为[0,1],设置前面4个子图的占的位置为[0,0.8]
          fig1.subplots_adjust(right=0.8)
          #在原fig1上添加一个子图句柄为cbar_ax, 设置其位置为[0.85,0.15,0.05,0.7]
          #colorbar 左 下 宽 高 
          l = 0.85
          b = 0.12
          w = 0.05
          h = 1 - 2*b 
          #对应 l,b,w,h;设置colorbar位置;
          rect = [l,b,w,h] 
          cbar_ax = fig1.add_axes(rect)
          ##设置一个fig2,其数值范围涵括fig1所有子图的数值范围
          fig2 = plt.figure(figsize = (18,6))
          all_data = np.random.randint(vmin,vmax,size = (20,20))
          h4 = plt.contourf(all_data,norm = norm)
          #设置fig1的colorbar对应fig2的数据范围
          cb = fig1.colorbar(h4, cax = cbar_ax) 
          #设置colorbar标签字体等
          cb.ax.tick_params(labelsize=16)  #设置色标刻度字体大小。
          font = {'family' : 'serif',
          #       'color'  : 'darkred',
              'color'  : 'black',
              'weight' : 'normal',
              'size'   : 16,
          cb.set_label('T' ,fontdict=font) #设置colorbar的标签字体及其大小
          plt.show()
          

          对比上述情况2的图片,情况有所改善,但是吊了一个尾巴。

          4.5 解决办法2:plt.imshow()
          import numpy as np
          import matplotlib.pyplot as plt
          a_list = [5,10,20,15]
          #设置colorbar的范围
          vmin = 0
          vmax = 20
          norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
          fig, axes = plt.subplots(nrows=2, ncols=2)
          for a,ax in zip(a_list,axes.flat):
              #设置每个子图
              data = np.random.randint(0,a,size = (20,20))
              im = ax.imshow(data , vmin = vmin, vmax = vmax )
          fig.colorbar(im, ax=axes.ravel().tolist())
          plt.show()
          

          使用这个方法可以解决上述情况2的问题,不需要吊个尾巴啦!

          至于使用plt.imshow 和 plt.contourf,看各自喜好!另外,建议多看看官网例子。

          [1] 解决python画图中colorbar设置刻度和标签字体大小

          [2] 使用matplotlib的示例:调整字体-设置刻度、坐标、colormap和colorbar等

          [3] matplotlib官网例子

          🌈颜色,不仅是视觉的享受,更是数据可视化的灵魂!在Matplotlib的世界里,plt.colorbar就像一根魔法棒,为你的图表增添色彩和深度。🎨 🌟从入门到精通,本文带你探索plt.colorbar的奥秘!无论是简单应用还是高级定制,你都能在这里找到答案。🛠️ 🔍详解plt.colorbar的关键参数,如extend、orientation和ticks,让你的颜色条更加精准、生动!🌈 cm1 = plt.cm.get_cmap('RdYlBu') cm2 = plt.cm.get_cmap('RdYlBu_r') # RdYlBu_r末尾加r表示颜色取反 x=np.random.randn(50) y=np.random.randn(50) plt.figure() 转载于:Matplotlib 系列:colorbar 的设置 该文为我很及时的解决了我的烦恼,再次向作者致意~ 作者一直在持续更新python系列,请支持原作者,文章来源:炸鸡人博客 0. 前言 承接 Matplotlib 系列:colormap 的设置 一文,这次介绍 colorbar。所谓 colorbar 即主图旁一个长条状的小图,能够辅助表示主图中 colormap 的颜色组成和颜色与数值的对应关系。本文将会依次介绍 colorbar 的基本用法、如何设置刻度,以及怎么为组图添加 colorbar。 几种图像读取方式总结 import matplotlib.image as img :img.imread() import PIL.Image as Img :Img.open() import tensorflow as tf :tf.read_file() import cv2:cv2.imread() 需要注意:一、对于低版本的tf,需要将图片经过tf.Session()执行 二、cv2读取文件中不能有中文字符 三、cv2读取三通道和单通道的不同 四、cv2的取的图片文件使用cv.imshow python很火,因为有各种库的支持,所以功能格外强大。在可视化方面,目前用得较多的是matplotlib. 在基于matplotlib.pyplot画带色标(colorbar)的图时候,往往为了美观和科研用途,需要对colorbar的Ticks(刻度) ,标签(label)和fonddict(字体进行设置)。但是很多初学者都苦于这些东西的设置,因为太麻烦了(别问我怎么知道的)。以下将介绍... 通过调整width参数可以控制颜色条的宽度,通过height参数可以控制颜色条的高度。在示例中,我将宽度设置为图形宽度的5%(“5%”),高度设置为图形高度的100%(“100%”),你可以根据需要自行调整这些值。colorbar()函数是用于在图形中添加颜色条的方法之一,它可以接受一些参数以控制颜色条的外观和布局。**问:**上面这个脚本中我试了好像没有吧colorbar的大小进行调节,只是调节了字体等,能不能把colorbar的主体大小也进行调节。通过以上方法,你可以自定义颜色条的大小来满足你的需求。
 
推荐文章
有胆有识的人字拖  ·  matplotlib 合理设置colorbar和子图的对应关系_plt.colorbar与子图的距离
3 天前
着急的野马  ·  matplotlib画3D图修改X,Y,Z,colorbar的刻度值 - nxf_rabbit75
3 天前
踏实的烤地瓜  ·  python python的matplotlib调整colorbar和图像的距离 matplotlib设置colorbar_温柔一刀的技术博客_
3 天前
爱逃课的墨镜  ·  在OpenResty中使用lua-zlib的方法 - 糖豆爸爸 - 博客园
1 年前
聪明的课本  ·  开源软件在地图数据处理中的应用 - 知乎
2 年前
帅气的青蛙  ·  MFC之使用 Windows 标准控件 - 御承扬 - 简书
2 年前
微笑的煎饼果子  ·  数亿数据MySQL撑不住,无缝迁移到MongoDB后稳得一批!-mysql数据迁移到mysql
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号