【问题标题】:matplotlib colorbar alternating top bottom labelsmatplotlib 颜色条交替顶部底部标签
【发布时间】:2016-05-11 11:17:27
【问题描述】:

首先,这是一个自我回答的问题,因为我相信它在某些情况下会有所帮助,例如在this post 作者试图隐藏所有其他标签以避免文本重叠,一种替代方法可能是交替标签位置,以便保留所有标签并避免重叠(如果没有疯狂标签数量)也是如此,这就是本文旨在解决的问题:

如何制作具有交替顶部和底部标签的matplotlib颜色条?

【问题讨论】:

    标签: python matplotlib labels colorbar


    【解决方案1】:

    跳转到一个简单的工作示例:

    import numpy
    import matplotlib.pyplot as plt
    
    #------------------Get some data------------------
    X = numpy.arange(100)
    Y = numpy.arange(100)
    Z = numpy.arange(100**2).reshape((100,100))
    
    levels=numpy.arange(0,100**2,1000)
    ltop=levels[::2]           # labels appear on top
    lbot=levels[1:][::2]       # labels appear at bottom
    
    #-----------------------Plot-----------------------
    f = plt.figure()
    ax = f.gca()
    
    cf = ax.contourf(X,Y,Z,100)
    cbar=plt.colorbar(cf,orientation='horizontal',ticks=lbot,drawedges=True)
    
    vmin=cbar.norm.vmin
    vmax=cbar.norm.vmax
    
    #-------------Print bottom tick labels-------------
    cbar.ax.set_xticklabels(lbot)
    
    #--------------Print top tick labels--------------
    for ii in ltop:
        cbar.ax.text((ii-vmin)/(vmax-vmin), 1.5, str(ii), transform=cbar.ax.transAxes, va='bottom', ha='center')
    
    plt.show(block=False)
    

    基本上,底部标签是使用默认方法cbar.ax.set_xticklabels(lbot) 绘制的。对于顶部标签,我使用 cbar.ax.text() 手动添加它们。

    剧情如下:

    编辑:我的答案的重要更新:

    当颜色条有扩展/溢出时,在相关端使用一个三角形来表示值溢出。在这种情况下,顶行刻度标签需要进行一些调整才能与颜色条部分正确对齐。

    默认情况下,三角形大小是颜色条轴的 5%,这用于获得适当的偏移和缩放以对齐标签。

    请参阅下面的示例,该示例在两端都有扩展。使用我之前的方法,结果是这样的:

    顶行的 2 个末端数字与三角形的尖端对齐。如果只有一端有extend,并且轮廓层数很大(>=10左右),错位会越来越严重。

    修正后的情节:

    这是生成正确绘图的代码:

    import numpy
    import matplotlib.pyplot as plt
    
    #------------------Get some data------------------
    X = numpy.linspace(-1,1,100)
    Y = numpy.linspace(-1,1,100)
    X,Y=numpy.meshgrid(X,Y)
    Z=numpy.sin(X**2)
    
    levels=numpy.linspace(-0.8,0.8,9)
    
    ltop=levels[::2]           # labels appear on top
    lbot=levels[1:][::2]       # labels appear at bottom
    
    #-----------------------Plot-----------------------
    f = plt.figure()
    ax = f.gca()
    
    cf = ax.contourf(X,Y,Z,levels,extend='both')
    cbar=plt.colorbar(cf,orientation='horizontal',ticks=lbot,drawedges=True)
    
    #------------Compute top tick label locations------------
    vmin=cbar.norm.vmin
    vmax=cbar.norm.vmax
    
    if cbar.extend=='min':
        shift_l=0.05
        scaling=0.95
    elif cbar.extend=='max':
        shift_l=0.
        scaling=0.95
    elif cbar.extend=='both':
        shift_l=0.05
        scaling=0.9
    else:
        shift_l=0.
        scaling=1.0
    
    #-------------Print bottom tick labels-------------
    cbar.ax.set_xticklabels(lbot)
    
    #--------------Print top tick labels--------------
    for ii in ltop:
        cbar.ax.text(shift_l + scaling*(ii-vmin)/(vmax-vmin),
            1.5, str(ii), transform=cbar.ax.transAxes,
            va='bottom', ha='center')
    
    plt.show(block=False)
    

    【讨论】:

      【解决方案2】:

      您可以添加一个双 Axes 对象并在那里设置每个奇数刻度,同时在原始 Axes 上设置每个偶数刻度。

      import numpy as np
      import matplotlib.pyplot as plt
      
      # Make the plot
      fig, ax = plt.subplots(1,1, figsize=(5,5))
      fig.subplots_adjust(bottom=0.2)
      ## Trick to have the colorbar of the same size as the plot
      box = ax.get_position() 
      cax = fig.add_axes([box.xmin, box.ymin - 0.1, box.width, 0.03])
      m = ax.matshow(np.random.random(100).reshape(10,10), aspect="auto") # Don't forget auto or the size of the heatmap will change.
      cb = plt.colorbar(m, cax=cax, orientation="horizontal")
      
      # Add twin axes 
      cax2 = cax.twiny()
      
      # get current positions and values of the ticks.
      # OR you can skip this part and set your own ticks instead.
      xt = cax.get_xticks()
      xtl = [i.get_text() for i in cax.get_xticklabels()]
      
      # set odd ticks on top (twin axe)
      cax2.set_xticks(xt[1::2])
      cax2.set_xticklabels(xtl[1::2])
      # set even ticks on  original axes (note the different object : cb != cax)
      cb.set_ticks(xt[::2])
      cb.set_ticklabels(xtl[::2])
      

      HTH

      【讨论】:

      • 我发现这不适用于使用matplotlib.colorbar.make_axes_gridspec() 创建的cax,生成的双轴比cax 长得多。
      猜你喜欢
      • 2016-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-07
      • 1970-01-01
      • 2012-03-17
      相关资源
      最近更新 更多