我注意到这里发布的所有使用的解决方案set_xticklabels()
都没有保留offset,这是一个应用于刻度值的缩放因子,以创建更好看的刻度标签。例如,如果刻度在 0.00001 (1e-5) 的数量级上,matplotlib 将自动添加比例因子(或offset
)1e-5
,因此生成的刻度标签可能最终为1 2 3 4
,而不是1e-5 2e-5 3e-5 4e-5
。
下面给出一个例子:
x
数组是,np.array([1, 2, 3, 4])/1e6
并且y
是y=x**2
。所以两者都是非常小的值。
左栏:按照@Joe Kington 的建议手动更改第一个和第三个标签。请注意,偏移量会丢失。
中列:与@iipr 建议的类似,使用FuncFormatter
.
右栏:我建议的保留偏移解决方案。
如图:
完整代码在这里:
import matplotlib.pyplot as plt
import numpy as np
# create some *small* data to plot
x = np.arange(5)/1e6
y = x**2
fig, axes = plt.subplots(1, 3, figsize=(10,6))
#------------------The set_xticklabels() solution------------------
ax1 = axes[0]
ax1.plot(x, y)
fig.canvas.draw()
labels = [item.get_text() for item in ax1.get_xticklabels()]
# Modify specific labels
labels[1] = 'Testing'
labels[3] = 'Testing2'
ax1.set_xticklabels(labels)
ax1.set_title('set_xticklabels()')
#--------------FuncFormatter solution--------------
import matplotlib.ticker as mticker
def update_ticks(x, pos):
if pos==1:
return 'testing'
elif pos==3:
return 'testing2'
else:
return x
ax2=axes[1]
ax2.plot(x,y)
ax2.xaxis.set_major_formatter(mticker.FuncFormatter(update_ticks))
ax2.set_title('Func Formatter')
#-------------------My solution-------------------
def changeLabels(axis, pos, newlabels):
'''Change specific x/y tick labels
Args:
axis (Axis): .xaxis or .yaxis obj.
pos (list): indices for labels to change.
newlabels (list): new labels corresponding to indices in <pos>.
'''
if len(pos) != len(newlabels):
raise Exception("Length of <pos> doesn't equal that of <newlabels>.")
ticks = axis.get_majorticklocs()
# get the default tick formatter
formatter = axis.get_major_formatter()
# format the ticks into strings
labels = formatter.format_ticks(ticks)
# Modify specific labels
for pii, lii in zip(pos, newlabels):
labels[pii] = lii
# Update the ticks and ticklabels. Order is important here.
# Need to first get the offset (1e-6 in this case):
offset = formatter.get_offset()
# Then set the modified labels:
axis.set_ticklabels(labels)
# In doing so, matplotlib creates a new FixedFormatter and sets it to the xaxis
# and the new FixedFormatter has no offset. So we need to query the
# formatter again and re-assign the offset:
axis.get_major_formatter().set_offset_string(offset)
return
ax3 = axes[2]
ax3.plot(x, y)
changeLabels(ax3.xaxis, [1, 3], ['Testing', 'Testing2'])
ax3.set_title('With offset')
fig.show()
plt.savefig('tick_labels.png')
警告:似乎使用 的解决方案set_xticklabels()
(包括我自己的)依赖于FixedFormatter
,它是静态的并且不响应图形调整大小。要观察效果,请将图形更改为较小的尺寸,例如fig, axes = plt.subplots(1, 3, figsize=(6,6))
放大图形窗口。您会注意到只有中间列响应调整大小并随着图形变大添加更多刻度。左右列将有空的刻度标签(见下图)。
警告 2:我还注意到,如果您的刻度值是浮点数,则set_xticklabels(ticks)
直接调用可能会给您带来难看的字符串,例如1.499999999998
代替1.5
.