from matplotlib import ticker
import numpy as np
def ticks_format(value, index):
"""
get the value and returns the value as:
integer: [0,99]
1 digit float: [0.1, 0.99]
n*10^m: otherwise
To have all the number of the same size they are all returned as latex strings
"""
exp = np.floor(np.log10(value))
base = value/10**exp
if exp == 0 or exp == 1:
return '${0:d}$'.format(int(value))
if exp == -1:
return '${0:.1f}$'.format(value)
else:
return '${0:d}\\times10^{{{1:d}}}$'.format(int(base), int(exp))
subs = [1.0, 2.0, 3.0, 6.0] # ticks to show per decade
ax.xaxis.set_minor_locator(ticker.LogLocator(subs=subs)) #set the ticks position
ax.xaxis.set_major_formatter(ticker.NullFormatter()) # remove the major ticks
ax.xaxis.set_minor_formatter(ticker.FuncFormatter(ticks_format)) #add the custom ticks
#same for ax.yaxis
3条答案
按热度按时间fykwrbwg1#
您可以在相应的轴上使用
set_minor_tickformatter
:ljo96ir52#
我尝试过很多方法来让小刻度在对数图中正常工作。如果你对显示刻度值的对数很满意,你可以使用
matplotlib.ticker.LogFormatterExponent
。我记得尝试过matplotlib.ticker.LogFormatter
,但我不太喜欢它:如果我没记错的话,它把所有的东西都放在base^exp
中(也是0.1,0,1)。在这两种情况下(以及所有其他的matplotlib.ticker.LogFormatter*
),你必须设置labelOnlyBase=False
来获得次要的刻度。我最终创建了一个自定义函数并使用了
matplotlib.ticker.FuncFormatter
。我的方法假设刻度是整数值,并且您需要一个以10为底的日志。如果你不删除主刻度并使用
subs = [2.0, 3.0, 6.0]
,主刻度和次刻度的字体大小是不同的(这可能是由于在我的matplotlibrc
中使用text.usetex:False
造成的)2fjabf4q3#
我认为值得一提的是matplotlib 2.0版本中引入的选项“minor_thresholds”(文档链接)。它是LogFormatter类的一个参数对(subset,all)的形式,允许您指定何时显示次要ticklabels的(固定)子集,以及何时显示所有次要ticklabels(这意味着什么的解释在底部)。
在下面的代码中,我通过使用相同的参数值(在本例中为(2,0.4))但更改x轴的限制来显示效果:
这将导致以下图:x1c 0d1x
您可以看到,在第二行中,ticklabels与第一行中没有使用格式化程序的ticklabels相同。这是因为view-range的log大于2(参数对的第一个值)或者换句话说,视图跨越的范围大于两个主要ticklabel之间的范围。在第三行视图小于2但大于0.4(参数对的第二个值),因此我们看到次要ticklabels的子集。最后,在最后一行视图跨越两个主要ticklabels之间的空间小于0.4,因此显示所有次要ticklabels。