【问题标题】:One colorbar for several subplots in symmetric logarithmic scaling对称对数缩放中多个子图的一个颜色条
【发布时间】:2017-02-05 09:17:45
【问题描述】:

我需要为一行子图共享相同的颜色条。每个子图对颜色函数都有一个对称的对数缩放。这些任务中的每一个都有一个很好的解决方案,这里在 stackoverflow 上进行了解释:For sharing the color barfor nicely formatted symmetric logarithmic scaling

但是,当我在同一代码中结合这两种技巧时,颜色栏“忘记”了应该是对称对数的。有没有办法解决这个问题?

测试代码如下,为此我以明显的方式结合了上面的两个参考:

import numpy as np                                                                                  
import matplotlib.pyplot as plt                                                                     
from mpl_toolkits.axes_grid1 import ImageGrid                                                       
from matplotlib import colors, ticker                                                               

# Set up figure and image grid                                                                      
fig = plt.figure(figsize=(9.75, 3))                                                                 

grid = ImageGrid(fig, 111,          # as in plt.subplot(111)                                        
                 nrows_ncols=(1,3),                                                                 
                 axes_pad=0.15,                                                                     
                 share_all=True,                                                                    
                 cbar_location="right",                                                             
                 cbar_mode="single",                                                                
                 cbar_size="7%",                                                                    
                 cbar_pad=0.15,                                                                     
                 )                                                                                  

data = np.random.normal(size=(3,10,10))                                                             
vmax = np.amax(np.abs(data))                                                                        

logthresh=4                                                                                         
logstep=1                                                                                           
linscale=1                                                                                          

maxlog=int(np.ceil(np.log10(vmax)))                                                                 

#generate logarithmic ticks                                                                         
tick_locations=([-(10**x) for x in xrange(-logthresh, maxlog+1, logstep)][::-1]                     
                +[0.0]                                                                              
                +[(10**x) for x in xrange(-logthresh,maxlog+1, logstep)] )                          

# Add data to image grid                                                                            
for ax, z in zip(grid,data):                                                                        
    print z                                                                                         
    im = ax.imshow(z, vmin=-vmax, vmax=vmax,                                                        
                   norm=colors.SymLogNorm(10**-logthresh, linscale=linscale))                       

# Colorbar                                                                                          
ax.cax.colorbar(im,ticks=tick_locations, format=ticker.LogFormatter())                              
ax.cax.toggle_label(True)                                                                           

#plt.tight_layout()    # Works, but may still require rect paramater to keep colorbar labels visible
plt.show()

生成的输出如下:

【问题讨论】:

    标签: python matplotlib scaling subplot colorbar


    【解决方案1】:

    这就是你想要达到的目标吗?

    import numpy as np                                                                                  
    import matplotlib.pyplot as plt                                                                     
    from mpl_toolkits.axes_grid1 import ImageGrid                                                       
    from matplotlib import colors, ticker                                                               
    
    # Set up figure and image grid                                                                      
    fig = plt.figure(figsize=(9.75, 3))                                                                 
    
    grid = ImageGrid(fig, 111,          # as in plt.subplot(111)                                        
                     nrows_ncols=(1,3),                                                                 
                     axes_pad=0.15,                                                                     
                     share_all=True                                                                                                                                        
                     )                                                                                  
    
    data = np.random.normal(size=(3,10,10))                                                             
    vmax = np.amax(np.abs(data))                                                                        
    
    logthresh=4                                                                                         
    logstep=1                                                                                           
    linscale=1                                                                                          
    
    maxlog=int(np.ceil(np.log10(vmax)))                                                                 
    
    #generate logarithmic ticks                                                                         
    tick_locations=([-(10**x) for x in xrange(-logthresh, maxlog+1, logstep)][::-1]                     
                    +[0.0]                                                                              
                    +[(10**x) for x in xrange(-logthresh,maxlog+1, logstep)] )                          
    
    
    # Add data to image grid                                                                            
    for ax, z in zip(grid,data):                                                                        
        print z                                                                                        
        im = ax.imshow(z, vmin=-vmax, vmax=vmax,                                                        
                       norm=colors.SymLogNorm(10**-logthresh, linscale=linscale)) 
    
    cbaxes = fig.add_axes([0.9, 0.125, 0.02, 0.77])                     
    fig.colorbar(im, format=ticker.LogFormatter(), ticks=tick_locations, cax = cbaxes)
    ax.cax.toggle_label(True)   
    
    
    #plt.tight_layout()    # Works, but may still require rect paramater to keep colorbar labels visible
    plt.show()
    

    输出:

    【讨论】:

    • 是的,这正是我想要实现的,谢谢!根据您的回答,我设法修改了我的原始示例代码,使其无需像在您的解决方案中那样手动调整轴尺寸即可运行。我将把它作为一个单独的答案发布,因为我认为这将是这样做的首选方法。
    【解决方案2】:

    根据 Erba Aitbayev 的解决方案,我发现替换行就足够了

    ax.cax.colorbar(im,ticks=tick_locations, format=ticker.LogFormatter())
    

    在最初由该行发布的示例代码中

    fig.colorbar(im,ticks=tick_locations, format=ticker.LogFormatter(), cax = ax.cax)
    

    并且无需为颜色条指定明确的尺寸,一切正常。不过,我不知道为什么一个有效而另一个无效。最好添加相应的评论in the post on sharing colorbars。我检查了,如果在上述两个替代方案中的第二个中调用 colorbar,则该示例中的线性色标仍然有效。 (我没有足够的声誉在那里添加评论。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-14
      • 1970-01-01
      • 1970-01-01
      • 2016-01-16
      • 1970-01-01
      • 2015-04-06
      相关资源
      最近更新 更多