我想对图中选定的几个勾号标签做一些修改。

例如,如果我这样做:

label = axes.yaxis.get_major_ticks()[2].label
label.set_fontsize(size)
label.set_rotation('vertical')

更改了标记标签的字体大小和方向。

然而,如果尝试:

label.set_text('Foo')

没有修改勾号标签。如果我这样做:

print label.get_text()

什么都没有印出来。

这里还有一些奇怪的事情。当我试着这样做时:

import matplotlib.pyplot as plt
import numpy as np

axes = plt.figure().add_subplot(111)
t = np.arange(0.0, 2.0, 0.01)
s = np.sin(2*np.pi*t)
axes.plot(t, s)
for ticklabel in axes.get_xticklabels():
    print(ticklabel.get_text())

只打印空字符串,但plot包含标记为'0.0'、'0.5'、'1.0'、'1.5'和'2.0'的刻度。


当前回答

我注意到这里发布的所有使用set_xticklabels()的解决方案都没有保留偏移量,偏移量是应用于tick值以创建更好看的tick标签的缩放因子。例如,如果刻度在0.00001 (1e-5)量级,matplotlib将自动添加1e-5的缩放因子(或偏移量),因此最终的刻度标签可能是1 2 3 4,而不是1e-5 2e-5 3e-5 4e-5。

下面是一个例子:

x数组是np。数组([1,2,3,4])/1e6,并且y=x**2。所以两个值都很小。

左栏:按照@Joe Kington的建议手动更改第1和第3个标签。注意,偏移量丢失了。

中间列:类似于@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:我还注意到,如果tick值是浮点数,直接调用set_xticklabels(ticks)可能会得到难看的字符串,比如1.499999999998而不是1.5。

其他回答

axes类有一个set_yticklabels函数,它允许你设置tick标签,如下所示:

#ax is the axes instance
group_labels = ['control', 'cold treatment',
             'hot treatment', 'another treatment',
             'the last one']

ax.set_xticklabels(group_labels)

我仍在研究为什么你上面的例子不起作用。

matplotlib.axes.Axes.set_xticks, or matplotlib.axes.Axes.set_yticks for the y-axis, can be used to change the ticks and labels beginning with matplotlib 3.5.0. These are for the object oriented interface. If using the pyplot state-based interface, use plt.xticks or plt.yticks, as shown in other answers. In general terms, pass a list / array of numbers to the ticks parameter, and a list / array strings to the labels parameter. In this case, the x-axis is comprised of continuous numeric values, so there are no set Text labels, as thoroughly explained in this answer. This is not the case when plots have discrete ticks (e.g. boxplot, barplot). [Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, '')] is returned by ax.get_xticklabels() [-0.25 0. 0.25 0.5 0.75 1. 1.25 1.5 1.75 2. 2.25] is returned by ax.get_xticks() type(ax.get_xticks()) is <class 'numpy.ndarray'> type(ax.get_xticks()[0]) is <class 'numpy.float64'> Since the OP is trying to replace a numeric label with a str, all of the values in the ndarray must be converted to str type, and the value to be changed can be updated. Tested in python 3.10 and matplotlib 3.5.2

import numpy as np
import matplotlib.pyplot as plt

# create figure and axes
fig, ax = plt.subplots(figsize=(8, 6))

# plot data
t = np.arange(0.0, 2.0, 0.01)
s = np.sin(2*np.pi*t)

# plot
ax.plot(t, s)

# get the xticks, which are the numeric location of the ticks
xticks = ax.get_xticks()

# get the xticks and convert the values in the array to str type
xticklabels = list(map(str, ax.get_xticks()))

# update the string to be changed
xticklabels[1] = 'Test'

# set the xticks and the labels
_ = ax.set_xticks(xticks, xticklabels)

注意,更改xticklabels时,x轴偏移量不会保留。但是,正确的值没有偏移量。

# create figure and axes
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 6), sharex=False)

# plot data
t = np.linspace(0, 1500000, 100)
s = t**2

# plot
ax1.plot(t, s)
ax2.plot(t, s)

# get the xticks, which are the numeric location of the ticks
xticks = ax2.get_xticks()

# get the xticks and convert the values in the array to str type
xticklabels = list(map(str, ax2.get_xticks()))

# update the string to be changed
xticklabels[1] = 'Test'

# set the xticks and the labels
_ = ax2.set_xticks(xticks, xticklabels, rotation=90)

注意:除非ticklabels已经设置为字符串(通常在箱线图中是这样),否则这将不适用于任何更新于1.1.0的matplotlib版本。如果你正在从当前的github master工作,这将不起作用。我还不确定是什么问题……这可能是一个无意的变化,也可能不是……

通常情况下,你会这样做:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

# We need to draw the canvas, otherwise the labels won't be positioned and 
# won't have values yet.
fig.canvas.draw()

labels = [item.get_text() for item in ax.get_xticklabels()]
labels[1] = 'Testing'

ax.set_xticklabels(labels)

plt.show()

要理解为什么需要跳过这么多步骤,您需要更多地了解matplotlib的结构。

Matplotlib故意避免对刻度等进行“静态”定位,除非明确地告诉它这样做。假设您希望与图形交互,因此图形的边界、刻度、刻度标签等将动态变化。

因此,不能只设置给定标记标签的文本。默认情况下,每次绘制图形时,它都会被轴的Locator和Formatter重新设置。

但是,如果Locators和Formatters被设置为静态(分别为FixedLocator和FixedFormatter),则标记标签保持不变。

这就是set_*ticklabels或ax.*axis。set_ticklabels。

希望这能让您更清楚地了解为什么更改单个标记有点复杂。

通常,你真正想做的只是注释一个特定的位置。在这种情况下,请查看注释。

试试这个:

  fig,axis = plt.subplots(nrows=1,ncols=1,figsize=(13,6),sharex=True)
  axis.set_xticklabels(['0', 'testing', '10000', '20000', '30000'],fontsize=22)

这也适用于matplotlib 3:

x1 = [0,1,2,3]
squad = ['Fultz','Embiid','Dario','Simmons']

plt.xticks(x1, squad, rotation=45)