Python 修改勾号标签文本

Python 修改勾号标签文本,python,matplotlib,Python,Matplotlib,我想对绘图中的几个选定记号标签进行一些修改 例如,如果我这样做: label = axes.yaxis.get_major_ticks()[2].label label.set_fontsize(size) label.set_rotation('vertical') 勾号标签的字体大小和方向已更改 但是,如果尝试: label.set_text('Foo') 不修改勾号标签。如果我这样做: print label.get_text() 没有打印任何内容 还有一些奇怪的地方。当我尝试这样做

我想对绘图中的几个选定记号标签进行一些修改

例如,如果我这样做:

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”的记号。

axes类具有一个函数,允许您设置记号标签,如下所示:

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

ax.set_xticklabels(group_labels)

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

警告:除非ticklabels已设置为字符串(如方框图中的通常情况),否则这将不适用于任何比
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故意避免对记号等进行“静态”定位,除非明确要求这样做。假设您希望与绘图交互,因此绘图的边界、记号、标签等将动态更改

因此,不能只设置给定记号标签的文本。默认情况下,每次绘制绘图时,轴的定位器和格式设置程序都会重新设置它

但是,如果定位器和格式化程序设置为静态(
FixedLocator
FixedFormatter
),则记号标签保持不变

这就是
set_*ticklabels
ax.*axis.set_ticklabels
所做的

希望这能让我们更清楚地了解为什么更改单个蜱虫标签有点复杂

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

您可以执行以下操作:

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

draw()

在较新版本的
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()
它适用于从
1.1.1rc1
到当前版本
2.0

的版本,也可以使用pylab和xticks来实现这一点

这项工作:

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)

这个问题已经问了很久了。截至今天(
matplotlib 2.2.2
),经过一些阅读和试用,我认为最好/正确的方法是:

Matplotlib有一个名为“包含支持完全可配置的记号定位和格式设置的类”的模块。要修改绘图中的特定记号,以下操作对我有效:

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轴
mticker
有另一个名为
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
是小数点后的小数位数。

这也适用于matplotlib 3:

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

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

如果您不使用
fig
ax
并且希望修改所有标签(例如,用于标准化),则可以执行以下操作:

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

试试这个:

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

我注意到这里发布的所有使用
setxticklabels()
的解决方案都没有保留偏移量,这是应用于刻度值的比例因子,用于创建外观更好的刻度标签。例如,如果记号的数量级为0.00001(1e-5),matplotlib将自动添加
1e-5
的比例因子(或
offset
),因此生成的记号标签可能最终成为
1234
,而不是
1e-52E-53E-54E-5

下面是一个例子:

x
数组是
np.array([1,2,3,4])/1e6
y
y=x**2
。所以两者都是非常小的值

左栏:根据@Joe Kington的建议,手动更改第一个和第三个标签。请注意,偏移丢失

中列:与@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')

导入matplotlib.pyplot作为plt
将numpy作为np导入
#创建一些要打印的*小*数据
x=np.arange(5)/1e6
y=x**2
图,轴=plt.子批次(1,3,figsize=(10,6))
#------------------set_xticklabels()解------------------
ax1=轴[0]
ax1.绘图(x,y)
图canvas.draw()
labels=[item.get_text(),用于ax1.get_xticklabels()中的项]
#修改特定标签
标签[1]=“测试”
标签[3]=“测试2”
ax1.设置标签(标签)
ax1.set_title('set_xticklabels()'))
#--------------函数格式化程序解决方案--------------
将matplotlib.ticker作为mticker导入
def更新标记(x,位置):
如果pos==1:
返回“测试”
elif pos==3:
返回“testing2”
其他:
返回x
ax2=轴[1]
ax2.绘图(x,y)
ax2.xaxis.set\u major\u格式化程序(mticker.FuncFormatter(更新标记))
ax2.set_title('Func Formatter')
#-------------------我的解决方案-------------------
def更改标签(轴、位置、新标签):
  fig,axis = plt.subplots(nrows=1,ncols=1,figsize=(13,6),sharex=True)
  axis.set_xticklabels(['0', 'testing', '10000', '20000', '30000'],fontsize=22)
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')