title: formatting the colorbar ticklabels with SymLogNorm normalization in matplotlib
body: <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 noreferrer">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 noreferrer">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="https://i.stack.imgur.com/fx5nN.png" rel="nofollow noreferrer"><img src="https://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="https://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 https://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="https://i.stack.imgur.com/iMJoV.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/iMJoV.png" alt="imshow with SymLogNorm normalization"></a></p>