Одна цветовая полоса для нескольких подграфиков в симметричном логарифмическом масштабировании

Мне нужно использовать одну и ту же цветовую полосу для ряда подзаголовков. Каждый подграфик имеет симметричное логарифмическое масштабирование функции цвета. Для каждой из этих задач есть хорошее решение, объясненное здесь, в stackoverflow: для совместного использования цветной полосы и для красиво отформатированного симметричного логарифмического масштабирования.

Однако, когда я комбинирую оба приема в одном коде, цветовая полоса «забывает», что должна быть симметричной логарифмической. Есть ли способ обойти эту проблему?

Тестовый код выглядит следующим образом, для которого я объединил две приведенные выше ссылки очевидным образом:

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()

Сгенерированный вывод выглядит следующим образом: введите здесь описание изображения


person mjo    schedule 27.09.2016    source источник


Ответы (2)


Это то, чего вы пытаетесь достичь?

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()

Вывод: введите здесь описание изображения

person Erba Aitbayev    schedule 27.09.2016
comment
Да, именно этого я и добивался, спасибо! Основываясь на вашем ответе, мне удалось изменить исходный код примера, чтобы он работал без необходимости ручной настройки размеров осей, как в вашем решении. Я опубликую это как отдельный ответ, так как думаю, что это был бы предпочтительный метод для этого. - person mjo; 27.09.2016

Опираясь на решение Эрбы Айтбаева, я пришел к выводу, что достаточно заменить строку

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

в примере кода, изначально размещенном строкой

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

и все работает без необходимости указывать явные размеры для цветовой полосы. Я понятия не имею, почему один работает, а другой нет. Было бы неплохо добавить соответствующий комментарий в сообщение о совместном использовании цветовых полос. Я проверил, и линейная цветовая шкала в этом примере все еще работает, если цветная полоса вызывается, как во втором из двух вариантов выше. (У меня недостаточно репутации, чтобы добавить комментарий.)

person mjo    schedule 27.09.2016