使用对数刻度时获取 yticks

Getting yticks when using log scale

我正在创建一个带有对数刻度(以 2 为底)的色标,并试图从颜色条中获取 yticks 以用于其他地方。但是,图中显示的内容与从 get_yticks() 中获得的内容不同:图形显示 [1,2,4,8,16],而方法显示 [ 0.5 1. 2. 4. 8. 16. 32. ]。难道我做错了什么?一般来说,我应该忽略第一个和最后一个条目(出于某种原因)吗?

示例代码如下所示:

from matplotlib.figure import Figure 
from matplotlib.colors import LogNorm
from matplotlib.ticker import FuncFormatter


x = [0, 1, 2, 3, 4]
y = [0, 1, 2, 3, 4]
z = [[1, 1, 1, 1], [8, 8, 8, 8], [2, 2, 2, 2], [16, 16, 16, 16]]

# Creating figure and axis
fig = Figure(figsize=(4.0, 4.0))
ax = fig.subplots(1, 1)
fig.subplots_adjust(left=0.20, right=0.80, bottom=0.070,top=0.92)

# Plotting and getting colorbar
cbar = ax.pcolor(x, y, z, cmap='turbo', norm=LogNorm(1, 16))

# Getting axis extent
bbox = ax.get_window_extent().transformed(fig.transFigure.inverted())
# Creating axis for colorbar
cax = fig.add_axes([1.05*bbox.x1, bbox.y0, 0.1*(bbox.x1-bbox.x0), (bbox.y1-bbox.y0)])

# Adding colorbar
fig.colorbar(cbar, cax=cax)
# Setting logarithm scale without decimals
cax.set_yscale('log', base=2)
formatter = FuncFormatter(lambda y, _: '{:.0f}'.format(y))
cax.yaxis.set_major_formatter(formatter)

# Getting ticks
print(cax.get_yticks())  # Output: [ 0.5  1.   2.   4.   8.  16.  32. ]

fig.savefig('log_test.pdf')

产生这个数字:

编辑: 我注意到即使在使用对数刻度的简单绘图中,get_yticks() 返回的刻度也是“错误的”。这是一个例子:

from matplotlib.figure import Figure 
from matplotlib.ticker import FuncFormatter

x = [0, 1, 2, 3, 4]
y = [1, 1, 1, 1, 1]

fig = Figure(figsize=(4.0, 4.0))
ax = fig.subplots(1, 1)
fig.subplots_adjust(left=0.20, right=0.80, bottom=0.070,top=0.92)

ax.plot(x, y)

ax.set_yscale('log', base=2)
formatter = FuncFormatter(lambda y, _: '{:.0f}'.format(y))
ax.yaxis.set_major_formatter(formatter)

print(ax.get_yticks()) # Output: [0.125 0.25  0.5   1.    2.    4.    8.   ]

fig.savefig('log_test.pdf')

图形长这样:

然而,在这种情况下,返回值是 [0.125 0.25 0.5 1. 2. 4. 8. ],这表明我什至无法使用跳过第一个和最后一个值的解决方法。

虽然我正在寻找更好的解决方案 - 因为我仍然不理解 get_yticks() 的 return 值,我找到了一个解决方案来检查刻度是否在 ylim 范围内:

from matplotlib.figure import Figure
from matplotlib.ticker import FuncFormatter

x = [0, 1, 2, 3, 4]
y = [1, 1, 1, 1, 1]

fig = Figure(figsize=(4.0, 4.0))
ax = fig.subplots(1, 1)
fig.subplots_adjust(left=0.20, right=0.80, bottom=0.070, top=0.92)

ax.plot(x, y)

ax.set_yscale('log', base=2)
formatter = FuncFormatter(lambda y, _: '{:.0f}'.format(y))
ax.yaxis.set_major_formatter(formatter)

yticks = ax.get_yticks()
print(yticks)  # Output with extra ticks: [0.125 0.25  0.5   1.    2.    4.    8.   ]

ylim = ax.get_ylim()
print("ylim", ylim) # Output: ylim (0.4665164957684037, 2.1435469250725863)

print([tick for tick in yticks if ylim[0] <= tick <= ylim[1]]) # Desired output: [0.5, 1.0, 2.0]


fig.savefig('log_test.pdf')

这应该会删除所有不需要的标记。