我想对图中的几个选定的刻度标签进行修改。例如,如果我这样做了:

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


字体刻度标签的大小和方向已更改。

但是,如果尝试:

label.set_text('Foo')


刻度标签未修改。另外,如果我这样做:

print label.get_text()


什么也没打印。

这里还有一些奇怪之处。当我尝试以下操作时:

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


仅打印空字符串,但该图包含标有'0.0','0.5','1.0','1.5'的刻度和'2.0'。

评论

您可以提供用于获取标签的图吗?

由于尚未绘制画布,因此获得空白标签。如果您在尝试打印标签之前调用draw(),则会得到期望的结果。不幸的是,设置单个刻度标签会更加困难(发生的事情是刻度定位器和格式化程序尚未重置,并且在您设置set_text时会覆盖所有内容)。如果有人没有击败我,我会再举一个例子。不过,目前我必须坐公共汽车。

@JoeKington:太好了!期待看到您的修复。

@repoman-好吧,看来我讲得太早了。我的想法适用于较旧版本的matplotlib,但不适用于最新版本。我需要做更多的挖掘。话虽如此,这应该不那么复杂...

#1 楼

警告:除非ticklabel已设置为字符串(例如在boxplot中通常如此),否则这不适用于比1.1.0更高的任何matplotlib版本。如果您正在使用当前的github主机,则将无法使用。我不确定问题是什么...可能是意外更改,也可能不是...

通常,您会按照以下方式进行操作:

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故意避免对刻度等进行“静态”定位,除非明确告知。假设您想与图进行交互,因此图的边界,刻度,刻度标签等将动态变化。

因此,您不能只设置文本给定刻度线的标签。默认情况下,每次绘制图形时,都会通过轴的定位器和格式化程序将其重置。

但是,如果将定位器和格式化程序设置为静态(分别为FixedLocatorFixedFormatter),则刻度标签保持不变。

set_*ticklabelsax.*axis.set_ticklabels就是这样做的。

希望这样可以使我们更清楚地知道为什么更改单个刻度标签有些麻烦。

通常,您实际要做的只是注释某个位置。在这种情况下,请查看annotate

评论


这似乎不适用于当前版本(1.20)!

–安德鲁·贾菲(Andrew Jaffe)
13年13月13日在16:38

如果ticklabel已经设置为字符串,例如一个箱线图,这仍然有效。这可能很明显,但是由于答案的第一行是它不适用于较新的matplotlib版本,因此用户可能会完全跳过它(我起初是这样做的)。也许简短地提一下。

– joelostblom
2014年12月7日在22:15

我认为您可以将其压缩为plt.gca()。set_xticklabels(labels)

–alexey
17年8月5日,下午3:31

如果我想将“测试”的字体加粗,而其他人使用“轻”的字体加粗,该怎么办?有办法吗?

–steven
19年7月15日在5:29

对于那些在jupyter笔记本中使用它的用户可能会受益于指出fig.canvas.draw()是至关重要的

– wander95
1月3日21:07

#2 楼

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()


http://matplotlib.org/examples/ticks_and_spines/ticklabels_demo_rotation.html

评论


这是一个简单的解决方案,可用于pyplot 1.5.1。这应该被赞成。

–字匠
16-10-22在19:09

尽管这个问题并没有要求,但我很欣赏这个示例可以让您在修改刻度线的同时设置刻度线的位置。

–宣言
17年5月23日在1:11

来自现代的matplotlib文档:“不推荐使用pylab,并且强烈建议不要使用pylab,因为命名空间受到污染。请改用pyplot。”

–纳撒尼尔·琼斯(Nathaniel Jones)
2月21日21:06

#3 楼

在较新版本的matplotlib中,如果未使用一堆str值设置刻度标签,则默认情况下它们是''(绘制绘图时,标签只是刻度值)。知道这一点,要获得所需的输出,将需要以下内容:

>>> from pylab import *
>>> axes = figure().add_subplot(111)
>>> a=axes.get_xticks().tolist()
>>> a[1]='change'
>>> axes.set_xticklabels(a)
[<matplotlib.text.Text object at 0x539aa50>, <matplotlib.text.Text object at 0x53a0c90>, 
<matplotlib.text.Text object at 0x53a73d0>, <matplotlib.text.Text object at 0x53a7a50>, 
<matplotlib.text.Text object at 0x53aa110>, <matplotlib.text.Text object at 0x53aa790>]
>>> plt.show()


和结果:


现在如果您检查_xticklabels,它们将不再是一堆''

>>> [item.get_text() for item in axes.get_xticklabels()]
['0.0', 'change', '1.0', '1.5', '2.0']


它适用于从1.1.1rc1到当前版本2.0的版本。

评论


谢谢,这是我一直在寻找的答案。最清洁的解决方案IMO;只需为set_xticklabels提供字符串和刻度对象的混合列表即可。

–卢克·戴维斯(Luke Davis)
17年4月27日在8:35

请注意,如果将刻度标签设置为整数,这会将其更改为浮点型。容易解决,但值得注意。

–接近黑暗鱼
18年1月31日在22:14

这个工作了(ax.get_xticks()。tolist())。投票最多的解决方案没有(ax.get_xtickslabels())。尽管在我建议的情况下使用了fig.canvas.draw(),但在plt.show()被执行之前,它不知何故无法提取标签。

–CypherX
19/12/6在10:20

仅供参考,来自最新的matplotlib文档:“不赞成使用pylab,并且由于名称空间污染而强烈不建议使用pylab。请改用pyplot。”

–纳撒尼尔·琼斯(Nathaniel Jones)
2月21日21:09

用户警告:FixedFormatter仅应与FixedLocator一起使用

–baxx
12月8日15:46

#4 楼

自问这个问题已经有一段时间了。截止到今天(matplotlib 2.2.2),经过一些阅读和试验,我认为最好/正确的方法如下:

Matplotlib有一个名为ticker的模块,该模块“包含支持完全可配置的刻度定位和格式化的类。 ”。要修改绘图中的特定刻度,以下对我有用:

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

def update_ticks(x, pos):
    if x == 0:
        return 'Mean'
    elif pos == 6:
        return 'pos is 6'
    else:
        return x

data = np.random.normal(0, 1, 1000)
fig, ax = plt.subplots()
ax.hist(data, bins=25, edgecolor='black')
ax.xaxis.set_major_formatter(mticker.FuncFormatter(update_ticks))
plt.show()




注意! x是刻度的值,pos是其在轴上按顺序的相对位置。请注意,在索引时,pos的值以1开头,而不是通常的0


在我的情况下,我试图用百分比值格式化直方图的y-axismticker还有另一个名为PercentFormatter的类,可以轻松完成此操作而无需像以前那样定义单独的函数:

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

data = np.random.normal(0, 1, 1000)
fig, ax = plt.subplots()
weights = np.ones_like(data) / len(data)
ax.hist(data, bins=25, weights=weights, edgecolor='black')
ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=1.0, decimals=1))
plt.show()




情况xmax是对应于100%的数据值。百分比计算为x / xmax * 100,这就是为什么我们要固定xmax=1.0的原因。同样,decimals是该点之后要保留的小数位数。

#5 楼

axes类具有set_yticklabels函数,可让您设置刻度标签,如下所示:

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

ax.set_xticklabels(group_labels)


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

评论


但是我只想更改一个标签。上面的技巧要求您提取所有刻度标签并将所需的标签设置为新值。但是,当label.get_text()不返回任何内容时,如何提取刻度标签?

– repoman
2012年6月28日13:21

#6 楼

作品:

import matplotlib.pyplot as plt

fig, ax1 = plt.subplots(1,1)

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

ax1.set_xticks(x1)
ax1.set_xticklabels(squad, minor=False, rotation=45)




#7 楼

这也适用于matplotlib 3:

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

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


#8 楼

如果您不使用figax,并且想要修改所有标签(例如,用于规范化),则可以执行以下操作:

labels, locations = plt.yticks()
plt.yticks(labels, labels/max(labels))



#9 楼

试试这个:

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


#10 楼

我注意到此处发布的所有使用set_xticklabels()的解决方案都没有保留偏移量,偏移量是应用于刻度值以创建外观更好的刻度标签的比例因子。例如,如果刻度线约为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,而yy=x**2。因此,这两个值都非常小。
左列:手动更改第1和第3个标签,如@Joe Kington所建议。请注意,偏移量丢失了。
中间列:使用@ FuncFormatter表示与@iipr相似。
右边列:我建议的偏移量保留解决方案。
图此处:

在这里完成代码:
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


#11 楼

您可以执行以下操作:

for k in ax.get_xmajorticklabels():
    if some-condition:
        k.set_color(any_colour_you_like)

draw()


评论


有人可以解释为什么这个答案如此之低吗?

– HlynurDavíðHlynsson
19年7月1日在14:20

@HlynurDavíðHlynsson我认为这与问题无关。好吧,也许要进行一些编辑...如果可以将其与问题联系起来,请对其进行编辑。 ;)

–耶稣的喜爱
4月28日上午10:16