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