How can you...
Force the LogFormatter
to use scientific notation for every label? Now it uses it for values smaller than 0
or larger than 1000
. It does not seem to expose any set_powerlimit
method that I can find, either. Is there any way get it right or should you use a different formatter? which one?
Get the scientific notations with the exponents as superscripts like in the first plot attached, instead of things like -1e+02
? The plt.xscale('symlog')
call also gets it right for an x axis, so it doesn't look like a limitation of the scale itself...
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 documentation itself exhibits, I don't have much hope... :-/
Matplotlib offers a few normalizations that can be used with colorbar
. This is nicely explained in the documentation.
Among them, the logarithmic one (mpl.colors.LogNorm
) works specially well, as it
by itself. A minimal example:
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()
On the other hand, the symmetric logarithmic one (matplotlib.colors.SymLogNorm
) does neither.
This SO answer defines a wrapper function for imshow that goes a long way towards the desired results, but it does not quite get there yet.
A minimal example with an adaptation of that function:
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()
答案 0 :(得分:1)
Change the formatter in the function to LogFormatterMathtext
:
cb=plt.colorbar(ticks=tick_locations, format=ticker.LogFormatterMathtext())
The formatters obviously lack nice (if any) documentation, but this one seems to do what you want: