matplotlib - 用其他标签值替换日志格式的 xtick 标签值

matplotlib - replace xtick labels values with log format by others label values

我有以下代码片段来为 x 轴绘制对数刻度图:

# Number of values for loop
num_prior_loop = 100
# Declare prior array
prior_fish = np.zeros(num_prior_loop)
prior_start = 0
prior_end = 3
prior_fish = np.logspace(prior_start,prior_end,num_prior_loop)**2
# Declare FoM final array
FoM_final = np.zeros(num_prior_loop)
...

# Plot
fig, ax = plt.subplots()    
ax.plot(prior_fish, FoM_final)
#ax.set_xticks([np.linspace(prior_start,prior_end)])
#ax.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())
plt.xlabel(r'Prior on 5 ratios '+r'$\alpha = b_{sp}/b_{ph}$'+' in Fisher GCsp', fontsize=10)
plt.ylabel('FoM')
plt.title('FoM vs Prior - Prior on both GCsp and XC', fontsize=10)
plt.savefig('FoM_vs_Prior_alpha_on_both_GCsp_and_XC.pdf')

生成下图:

现在,我想做一个修改,就是让xtick 10^0 up to 10^6 自动被1, 10^-1, 10^-2, ... ., 10^-6.

我是自动说的,因为 2 个边界(1 和 10^-6)的开始和结束可能会有所不同。

更新 1: 我在下面的回答中尝试了 @max 建议的解决方案,但它失败了:

这是我得到的:

如果我这样做:

for txt in axs.get_xticklabels():
    # get position
    x,y = txt.get_position()
    print('x,y =', x,y)
    # value/formatting
    val = txt.get_text()
    # create new label
    if x == 1 or x == 0:
        val_new = f'${round(x)}$'
    else:
        val_new = '$\mathdefault{10^{' + f'{round(np.log10(1/x))}' + '}}$'
    # append
    xTickLabel.append( Text(x,y,val_new) )
# set labels
axs.set_xticklabels( xTickLabel )
# Plot and save
plt.plot(prior_fish, FoM_final)
plt.draw()
plt.savefig('FoM_vs_Prior_alpha_on_both_GCsp_and_XC.png')

我只得到零:

x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0

并打印 val returns 始终为空值。

这里是完整的代码:

# Plot
fig, axs = plt.subplots()
axs.set_xscale('log')
plt.draw()

plt.xlabel(r'Prior on 5 ratios '+r'$\alpha = b_{sp}/b_{ph}$'+' in Fisher GCsp', fontsize=10)
plt.ylabel('FoM')
plt.title('FoM vs Prior - Prior on both GCsp and XC', fontsize=10)
# create new labels
xTickLabel = []
for txt in axs.get_xticklabels():
    # get position
    x,y = txt.get_position()
    # value/formatting
    val = txt.get_text()
    # create new label
    if x == 1 or x == 0:
        val_new = f'${round(x)}$'
    else:
        val_new = '$\mathdefault{10^{' + f'{round(np.log10(1/x))}' + '}}$'
    # append
    xTickLabel.append( Text(x,y,val_new) )
# set labels
axs.set_xticklabels( xTickLabel )
# Plot and save
plt.plot(prior_fish, FoM_final)
plt.draw()
plt.savefig('FoM_vs_Prior.pdf')

错误在哪里?如何获取不同值的“0”和“1”以避免出现这种情况

   if x == 1 or x == 0:
        val_new = f'${round(x)}$'

看来您想直接修改文本标签。看看下面的代码。我们获取刻度的位置,反转 x-value,并更改 matplotlib.text.Text-object(或者更确切地说,我创建新的)。诀窍是位置保持不变;我们只是更改显示在 position/tick-label:

处的文本
from matplotlib import pyplot as plt
from matplotlib.text import Text

import numpy as np

fig, axs = plt.subplots(2,1)
# first axis
axs[0].set_xscale('log')
axs[0].set_yscale('log')
axs[0].scatter(2**np.arange(10), 2**np.arange(10))
plt.draw()

# second axis
axs[1].set_xscale('log')
axs[1].set_yscale('log')
axs[1].scatter(2**np.arange(10), 2**np.arange(10))


# create new labels
xTickLabel = []
for txt in axs[0].get_xticklabels():
    # get position
    x,y = txt.get_position()
    # value/formatting
    val = txt.get_text()
    # create new label
    if x == 1 or x == 0:
        val_new = f'${round(x)}$'
    else:
        val_new = '$\mathdefault{10^{' + f'{round(np.log10(1/x))}' + '}}$'
    # append
    xTickLabel.append( Text(x,y,val_new) )
# set labels
axs[1].set_xticklabels( xTickLabel )

plt.draw()