matplotlib 还显示次要刻度的标签

nzrxty8p  于 2023-10-24  发布在  其他
关注(0)|答案(3)|浏览(142)

matplotlib中,当我在一个轴上使用log刻度时,可能会发生该轴将没有主要刻度只有次要刻度。所以这意味着整个轴没有标签显示。
我如何指定我也需要小刻度的标签?
我试过:

plt.setp(ax.get_xticklabels(minor=True), visible=True)

……但没有奏效。

fykwrbwg

fykwrbwg1#

您可以在相应的轴上使用set_minor_tickformatter

from matplotlib import pyplot as plt
from matplotlib.ticker import FormatStrFormatter

axes = plt.subplot(111)
axes.loglog([3,4,7], [2,3,4])
axes.xaxis.set_minor_formatter(FormatStrFormatter("%.2f"))
plt.xlim(1.8, 9.2)
plt.show()

ljo96ir5

ljo96ir52#

我尝试过很多方法来让小刻度在对数图中正常工作。如果你对显示刻度值的对数很满意,你可以使用matplotlib.ticker.LogFormatterExponent。我记得尝试过matplotlib.ticker.LogFormatter,但我不太喜欢它:如果我没记错的话,它把所有的东西都放在base^exp中(也是0.1,0,1)。在这两种情况下(以及所有其他的matplotlib.ticker.LogFormatter*),你必须设置labelOnlyBase=False来获得次要的刻度。
我最终创建了一个自定义函数并使用了matplotlib.ticker.FuncFormatter。我的方法假设刻度是整数值,并且您需要一个以10为底的日志。

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

如果你不删除主刻度并使用subs = [2.0, 3.0, 6.0],主刻度和次刻度的字体大小是不同的(这可能是由于在我的matplotlibrc中使用text.usetex:False造成的)

2fjabf4q

2fjabf4q3#

我认为值得一提的是matplotlib 2.0版本中引入的选项“minor_thresholds”(文档链接)。它是LogFormatter类的一个参数对(subset,all)的形式,允许您指定何时显示次要ticklabels的(固定)子集,以及何时显示所有次要ticklabels(这意味着什么的解释在底部)。
在下面的代码中,我通过使用相同的参数值(在本例中为(2,0.4))但更改x轴的限制来显示效果:

import matplotlib.pyplot as plt
from matplotlib.ticker import LogFormatter
import numpy as np

fig, axes = plt.subplots(4, figsize=(12, 24))

dt = 0.01
t = np.arange(dt, 20.0, dt)

# first plot doesn't use a formatter
axes[0].semilogx(t, np.exp(-t / 5.0))
axes[0].set_xlim([0, 25])
axes[0].grid()

xlims = [[0, 25], [0.2, 8], [0.6, 0.9]]

for ax, xlim in zip(axes[1:], xlims):
    ax.semilogx(t, np.exp(-t / 5.0))
    formatter = LogFormatter(labelOnlyBase=False, minor_thresholds=(2, 0.4))
    ax.get_xaxis().set_minor_formatter(formatter)
    ax.set_xlim(xlim)
    ax.grid()

plt.show()

这将导致以下图:x1c 0d1x
您可以看到,在第二行中,ticklabels与第一行中没有使用格式化程序的ticklabels相同。这是因为view-range的log大于2(参数对的第一个值)或者换句话说,视图跨越的范围大于两个主要ticklabel之间的范围。在第三行视图小于2但大于0.4(参数对的第二个值),因此我们看到次要ticklabels的子集。最后,在最后一行视图跨越两个主要ticklabels之间的空间小于0.4,因此显示所有次要ticklabels。

相关问题