Search code examples
pythonmatplotlibaxesmultiple-axes

How to change the labels of an axis created with host_subplot (from AxesGrid toolkit)


The AxesGrid toolkit provides the function host_subplot, which makes possible the creation of multiple parallel axis, as show in the code bellow:

from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import matplotlib.pyplot as plt


host = host_subplot(111, axes_class=AA.Axes)
plt.subplots_adjust(bottom=0.15)
par2 = host.twiny()
par2.axis["bottom"] = par2.get_grid_helper().new_fixed_axis(loc="bottom", axes=par2, offset=(0, -30) )
par2.axis["bottom"].toggle(all=True)

Which creates the following figure: enter image description here

Now I would like to change the label of the second x axis added below the image. I tried the following (among other things):

from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import matplotlib.pyplot as plt


host = host_subplot(111, axes_class=AA.Axes)
par2 = host.twiny()
par2.axis["bottom"] = par2.get_grid_helper().new_fixed_axis(loc="bottom", axes=par2, offset=(0, -30) )

for item in par2.get_xticklabels(): 
    item.set_text('new label')

par2.axis["bottom"].toggle(all=True)

Sadly par2.get_xticklabels() does not seem to work as I naively expected (i.e. it does not return the labels of the x axis).

The most similar question I found adressing a similar issua was How to change the font size for multiple axes labels (created with host_subplot API), which changes the font size property (not individual labels attached to the xaxis ticks).


Solution

  • Well, one thing I learned while trying to find an answer for this: IPython is a really good helper.


    Anyway, to get to the point. There seems to be something buggy about setting the text by iterating for each entry via get_xticklabels(). By assigning with set_text(my_text), even though my_text does indeed pass in the Text object, for some reason it is not picking it up afterwards.

    Case in point:

    [item.set_text("Some Text") for item in par2.get_xticklabels()]
    
    for item in par2.get_xticklabels():
        print item
    
    # Prints
    Text(0,0,'Some Text')
    Text(0,0,'Some Text')
    Text(0,0,'Some Text')
    Text(0,0,'Some Text')
    Text(0,0,'Some Text')
    Text(0,0,'Some Text')
    
    # plt.show() does not display these changes.
    

    Thankfully (and oddly), setting the labels works when doing it via set_xticklabels()

    # Omitting rest of script.
    
    # Set as False or else the top axis also gets these labels.
    # Try commenting the line out to view what I mean.
    par2.axis["top"].set_visible(False)
    par2.set_xticklabels(["THIS", "IS", "PROBABLY", "A", "LITTLE", "BUG"])
    
    plt.show()
    

    The figure drawn in this case is what you're looking for:

    bottom axis tick labels


    To add to the hypothesis of this being a little bug, the output of the same print statement as before returns a similar representation as it did before.

    for item in par2.get_xticklabels():
        print item
    
    Text(0,0,'THIS')
    Text(0,0,'IS')
    Text(0,0,'PROBABLY')
    Text(0,0,'A')
    Text(0,0,'LITTLE')
    Text(0,0,'BUG')
    

    I am not the best with matplotlib, but this just seems iffy. Maybe someone with more knowledge can verify.