Search code examples
pythonmatplotlibcolorbar

Colorbar tick labels as log outputs


I am playing around with histogram2d and I am trying incorporate a color bar logarithmic values.

Here is my current code:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.colors import LinearSegmentedColormap


cmap = LinearSegmentedColormap.from_list('mycmap', ['black', 'maroon', 
                                                'crimson', 'orange', 'white'])

fig = plt.figure()
ax = fig.add_subplot(111)
H = ax.hist2d(gas_pos[:,0]/0.7, gas_pos[:,1]/0.7, cmap=cmap, 
            norm=matplotlib.colors.LogNorm(), bins=350, weights=np.log(gas_Temp))

ax.tick_params(axis=u'both', which=u'both',length=0)
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)

cb = fig.colorbar(H[3], ax=ax, shrink=0.8, pad=0.01, 
                orientation="horizontal", label=r'$\log T\ [\mathrm{K}]$')
cb.ax.set_xticklabels([1,2,3,4])
cb.update_ticks()

empty = Rectangle((0,0 ), 0, 0, alpha=0.0)
redshift = fig.legend([empty], [r'$z = 127$'], 
        loc='upper right', frameon=False, handlelength=0, handletextpad=0)
redshift.get_texts()[0].set_color('white')
#fig.add_artist(redshift)

plt.show()

enter image description here

The weights are values not passed through np.log() and are currently being normalized through LogNorm().

What I am trying to get is to have the colorbar tic labels to be the logarithmic values of what is currently there eg. 10**4 --> 4, 10**6 --> 6, etc.

I have tried changing the formatting and also passing through the logarithmic values of np.log(gas_Temp), but nothing is really working.


Solution

  • The idiomatic thing to do is use a LogFormatterExponent to do the formatting of your colorbar. That's exactly what you need: to display 10**x values as x, or in other words, to display y values as log10(x).

    Proof using dummy data:

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.colors import LogNorm
    from matplotlib.ticker import LogFormatterExponent # <-- one new import here
    
    # generate dummy data
    histdata = 10**(np.random.rand(200,200)*4 + 1)  # 10^1 -> 10^5
    
    # plot
    fig = plt.figure()
    ax = fig.add_subplot(111)
    
    ax.tick_params(axis=u'both', which=u'both',length=0)
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    
    im = plt.imshow(histdata,cmap='viridis',norm=LogNorm())
    cb = fig.colorbar(im, ax=ax, shrink=0.8, pad=0.01,
                      orientation="horizontal", label=r'$\log T\ [\mathrm{K}]$')
    
    # v-- one new line here
    cb.formatter = LogFormatterExponent(base=10) # 10 is the default
    cb.update_ticks()
    

    Compare the result of your original (left) with the modified version (right):

    original new formatted