添加字符串作为自定义x-ticks,但也保留现有的(数字)tick标签?matplotlib.pyplot.annotate的替代方案?

e4yzc0pl  于 2023-10-24  发布在  其他
关注(0)|答案(4)|浏览(114)

我试图制作一个图表,我有一些问题注解它。
我的图在x轴上有一个对数刻度,显示时间。我希望能够做的是保持现有的(但不可预测)100个单位、1000个单位、10000个单位等的数字刻度标签,但也可以向x轴添加自定义刻度标签,使其清楚地显示更多“人类可读”的时间间隔-例如,我希望能够标记“一周”,“一个月”、“6个月”等。
我可以使用matplotlib.pyplot.annotate()来标记点,但它并没有真正做到我想要的。我真的不想在我的图表上添加文本和箭头,我只是想添加一些额外的自定义刻度线。有什么想法吗?

9avjhtql

9avjhtql1#

如果你真的想添加额外的刻度,你可以使用axis.xaxis.get_majorticklocs()获取现有的刻度,添加任何你想添加的刻度,然后使用axis.xaxis.set_ticks(<your updated array>)设置刻度。
另一种方法是使用axvline添加垂直线。优点是您不必担心将自定义tick插入到现有数组中,但您必须手动注解行。
另一种方法是添加一个带有自定义刻度的链接轴。

snz8szmq

snz8szmq2#

来自http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.xticks:

# return locs, labels where locs is an array of tick locations and
# labels is an array of tick labels.
locs, labels = xticks()

因此,您需要做的就是获得locslabels,然后根据您的喜好修改labels(虚拟示例):

labels = ['{0} (1 day)','{0} (1 weak)', '{0} (1 year)']
new_labels = [x.format(locs[i]) for i,x  in enumerate(labels)]

然后运行:

xticks(locs, new_labels)
yhxst69z

yhxst69z3#

这是我的解决方案。主要优点是:

  • 您可以指定轴(用于双轴或同时使用多个轴)
  • 您可以指定轴(将刻度放在x轴或y轴上)
  • 您可以轻松地添加新的刻度,同时保留自动刻度
  • 如果你添加一个已经存在的记号,它会自动替换。

代码:

#!/usr/bin/python
from __future__ import division
import matplotlib.pyplot as plt
import numpy as np

#Function to add ticks
def addticks(ax,newLocs,newLabels,pos='x'):
    # Draw to get ticks
    plt.draw()

    # Get existing ticks
    if pos=='x':
        locs = ax.get_xticks().tolist()
        labels=[x.get_text() for x in ax.get_xticklabels()]
    elif pos =='y':
        locs = ax.get_yticks().tolist()
        labels=[x.get_text() for x in ax.get_yticklabels()]
    else:
        print("WRONG pos. Use 'x' or 'y'")
        return

    # Build dictionary of ticks
    Dticks=dict(zip(locs,labels))

    # Add/Replace new ticks
    for Loc,Lab in zip(newLocs,newLabels):
        Dticks[Loc]=Lab

    # Get back tick lists
    locs=list(Dticks.keys())
    labels=list(Dticks.values())

    # Generate new ticks
    if pos=='x':
        ax.set_xticks(locs)
        ax.set_xticklabels(labels)
    elif pos =='y':
        ax.set_yticks(locs)
        ax.set_yticklabels(labels)

#Get numpy arrays
x=np.linspace(0,2)
y=np.sin(4*x)

#Start figure
fig = plt.figure()
ax=fig.add_subplot(111)

#Plot Arrays
ax.plot(x,y)
#Add a twin axes
axr=ax.twinx()

#Add more ticks
addticks(ax,[1/3,0.75,1.0],['1/3','3/4','Replaced'])
addticks(axr,[0.5],['Miguel'],'y')

#Save figure
plt.savefig('MWE.pdf')
alen0pnh

alen0pnh4#

我喜欢Miguel上面的回答。工作得很好。然而,必须做一个小的调整。以下是:

# Get back tick lists
locs=Dticks.keys()
labels=Dticks.values()

必须更改为

# Get back tick lists
locs=list(Dticks.keys())
labels=list(Dticks.values())

因为,在Python 2.7+/3中,Dict.keys()和Dict.values()返回dict_keys和dict_values对象,matplotlib不喜欢(显然)。更多关于PEP 3106中的这两个对象。

相关问题