在 matplotlib 中使用 SymLogNorm 标准化格式化颜色条刻度标签 [英] formatting the colorbar ticklabels with SymLogNorm normalization in matplotlib
问题描述
TL;DR
你怎么...
-
强制
LogFormatter
对每个标签使用科学计数法吗?现在它用于小于0
或大于1000
的值.它似乎也没有公开我能找到的任何set_powerlimit
方法.有什么方法可以解决问题,还是应该使用不同的格式化程序?哪个? 获取以指数为上标的科学记数法,如附加的第一个图中,而不是像
-1e+02
这样的东西?plt.xscale('symlog')
调用也适用于 x 轴,因此它看起来不像是比例本身的限制...
当然,如果有一种更简单的方法可以在带有符号缩放的颜色图上获得格式良好的 xticks 和标签,那也很棒.但老实说,看看
另一方面,对称对数 (matplotlib.colors.SymLogNorm
) 两者都没有.
将函数中的格式化程序更改为
TL;DR
How can you...
Force the
LogFormatter
to use scientific notation for every label? Now it uses it for values smaller than0
or larger than1000
. It does not seem to expose anyset_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
? Theplt.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... :-/
Starting from the beginning...
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
- places the xticks evenly distributed.
- formats the ticklabels with a nice looking scientific notation**.
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()
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:
这篇关于在 matplotlib 中使用 SymLogNorm 标准化格式化颜色条刻度标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!