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

例如,如果我这样做:

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'的刻度。


当前回答

试试这个:

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

其他回答

在这里,我们打算修改Matplotlib中的一些tick标签,但没有副作用,这可以干净地工作,并保留偏移的科学符号。本解决方案中没有遇到其他一些答案中讨论的问题。

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

from matplotlib import rcParams
rcParams['axes.formatter.use_mathtext'] = True

class CustomScalarFormatter(matplotlib.ticker.ScalarFormatter):
    def __init__(self, useOffset=None, useMathText=None, useLocale=None, replace_values=([],[])):
        super().__init__(useOffset=None, useMathText=None, useLocale=None)
        self.replace_values = replace_values

    def __call__(self, x, pos=None):
        """
        Return the format for tick value *x* at position *pos*.
        """
        if len(self.locs) == 0:
            return ''
        elif x in self.replace_values[0]:
            idx = self.replace_values[0].index(x)
            return str(self.replace_values[1][idx])
        else:
            xp = (x - self.offset) / (10. ** self.orderOfMagnitude)
            if abs(xp) < 1e-8:
                xp = 0
            return self._format_maybe_minus_and_locale(self.format, xp)


z = np.linspace(0, 5000, 100)
fig, ax = plt.subplots()

xmajorformatter = CustomScalarFormatter(replace_values=([2000,0],['$x_0$','']))
ymajorformatter = CustomScalarFormatter(replace_values=([1E7,0],['$y_0$','']))
ax.xaxis.set_major_formatter(xmajorformatter)
ax.yaxis.set_major_formatter(ymajorformatter)

ax.plot(z,z**2)
plt.show()

我们在这里所做的是创建matplotlib.ticker. scalarformatter类的派生类,matplotlib默认使用它来格式化标签。代码从matplotlib源复制,但只有__call__函数被复制和修改。后

        elif x in self.replace_values[0]:
            idx = self.replace_values[0].index(x)
            return str(self.replace_values[1][idx])

是添加到__call__函数中执行替换工作的新行。派生类的优点是它继承了基类的所有特性,比如偏移量标记法、科学标记法,如果值很大的话就标记。结果是:

也可以使用pylab和xticks来实现这一点

import matplotlib
import matplotlib.pyplot as plt
x = [0,1,2]
y = [90,40,65]
labels = ['high', 'low', 37337]
plt.plot(x,y, 'r')
plt.xticks(x, labels, rotation='vertical')
plt.show()

https://matplotlib.org/stable/gallery/ticks_and_spines/ticklabels_rotation.html

试试这个:

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

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)

我注意到这里发布的所有使用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。