formatting the colorbar ticklabels with SymLogNorm normalization in matplotlib
<h1>TL;DR</h1>

<p>How can you...</p>

<ul>
<li><p>Force the <code>LogFormatter</code> to use scientific notation for every label? Now it uses it for values smaller than <code>0</code> or larger than <code>1000</code>. It does not seem to expose any <code>set_powerlimit</code> method that I can find, either. Is there any way get it right or should you use a different formatter? which one?</p></li>
<li><p>Get the scientific notations with the exponents as superscripts like in the first plot attached, instead of things like <code>-1e+02</code>? The <code>plt.xscale('symlog')</code> call also gets it right for an x axis, so it doesn't look like a limitation of the scale itself...</p></li>
</ul>

<p>Of course, if there were a simpler way to get nicely formatted xticks and labels on a colormap with symlog scaling, that'd be great too. But honestly, looking at the colorbars that the <a href="http://matplotlib.org/1.5.1/users/colormapnorms.html" rel="nofollow">documentation</a> itself exhibits, I don't have much hope... :-/</p>

<hr>

<h1>Starting from the beginning...</h1>

<p>Matplotlib offers a few normalizations that can be used with <code>colorbar</code>. This is nicely explained in the <a href="http://matplotlib.org/1.5.1/users/colormapnorms.html" rel="nofollow">documentation</a>.</p>

<p>Among them, the logarithmic one (<code>mpl.colors.LogNorm</code>) works specially well, as it</p>

<ol>
<li>places the xticks evenly distributed.</li>
<li>formats the ticklabels with a <em>nice looking</em> scientific notation**.</li>
</ol>

<p>by itself. A minimal example:</p>

<pre><code>import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors, ticker

data = np.arange(4).reshape(-1,1)+np.arange(4).reshape(1,-1)
data = 10**(data/2.)

plt.figure(figsize=(4,3))
plt.imshow(data, interpolation="None", cmap="gray", norm=colors.LogNorm())
plt.colorbar()
plt.show()
</code></pre>

<p><a href="http://i.stack.imgur.com/fx5nN.png" rel="nofollow"><img src="http://i.stack.imgur.com/fx5nN.png" alt="imshow with LogNorm normalization"></a></p>

<p>On the other hand, the symmetric logarithmic one (<code>matplotlib.colors.SymLogNorm</code>) does neither.
<a href="http://stackoverflow.com/a/23118662">This SO answer</a> defines a wrapper function for imshow that goes a long  way towards the desired results, but it does not quite get there yet.</p>

<p>A minimal example with an adaptation of that function:</p>

<pre><code>def imshow_symlog(arr, vmin=None, vmax=None, logthresh=5, logstep=1,
                  linscale=1, **kwargs):
    # Adapted from http://stackoverflow.com/a/23118662

    vmin = arr.min() if vmin is None else vmin
    vmax = arr.max() if vmax is None else vmax
    img=plt.imshow(arr,
                   vmin=float(vmin), vmax=float(vmax),
                   norm=colors.SymLogNorm(10**-logthresh, linscale=linscale),
                   **kwargs)

    maxlog=int(np.ceil(np.log10(vmax)))
    minlog=int(np.ceil(np.log10(-vmin)))

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

    cb=plt.colorbar(ticks=tick_locations, format=ticker.LogFormatter())
    return img,cb

data2 = data - data[::-1,::-1]
plt.figure(figsize=(4,3))  
img, cb = imshow_symlog(data2, interpolation="None", cmap="gray", logthresh=0)
plt.show()
</code></pre>

<p><a href="http://i.stack.imgur.com/iMJoV.png" rel="nofollow"><img src="http://i.stack.imgur.com/iMJoV.png" alt="imshow with SymLogNorm normalization"></a></p>

<p>Change the formatter in the function to <a href="http://matplotlib.org/api/ticker_api.html#matplotlib.ticker.LogFormatterMathtext" rel="nofollow"><code>LogFormatterMathtext</code></a>: </p>

<pre><code>cb=plt.colorbar(ticks=tick_locations, format=ticker.LogFormatterMathtext())
</code></pre>

<p>The formatters obviously lack nice (if any) documentation, but this one seems to do what you want:</p>

<p><a href="http://i.stack.imgur.com/mq8xF.png" rel="nofollow"><img src="http://i.stack.imgur.com/mq8xF.png" alt="enter image description here"></a></p>

python matplotlib