Matplotlib: Add strings as custom x-ticks but also keep existing (numeric) tick labels? Alternatives to matplotlib.pyplot.annotate? Matplotlib: Add strings as custom x-ticks but also keep existing (numeric) tick labels? Alternatives to matplotlib.pyplot.annotate? python python

Matplotlib: Add strings as custom x-ticks but also keep existing (numeric) tick labels? Alternatives to matplotlib.pyplot.annotate?


If you really want to add extra ticks, you can get the existing ones using axis.xaxis.get_majorticklocs(), add whatever you want to add, and then set the ticks using axis.xaxis.set_ticks(<your updated array>).

An alternative would be to add vertical lines using axvline. The advantage is that you don't have to worry about inserting your custom tick into the existing array, but you'll have to annotate the lines manually.

Yet another alternative would be to add a linked axis with your custom ticks.


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

So all you should need to do is obtain the locs and labels and then modify labels to your liking (dummy example):

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

and then run:

xticks(locs, new_labels)


This is my solution. The main advantages are:

  • You can specify the axes (useful for twin axes or if working with multiple axes simultaneously)
  • You can specify the axis (put ticks on x-axis or y-axis)
  • You can easily add new ticks while keeping the automatic ones
  • It automatically replaces if you add a tick that already exists.

Code:

#!/usr/bin/pythonfrom __future__ import divisionimport matplotlib.pyplot as pltimport numpy as np#Function to add ticksdef 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 arraysx=np.linspace(0,2)y=np.sin(4*x)#Start figurefig = plt.figure()ax=fig.add_subplot(111)#Plot Arraysax.plot(x,y)#Add a twin axesaxr=ax.twinx()#Add more ticksaddticks(ax,[1/3,0.75,1.0],['1/3','3/4','Replaced'])addticks(axr,[0.5],['Miguel'],'y')#Save figureplt.savefig('MWE.pdf')