pythonmatplotlib

Enforcing matplotlib tick labels not wider than the axes


I need to make a very compact plot with shared y-axis using matplotlib. To make it compact and neat, I will not have any wspace. It looks good with my data.

But the x-tick labels overlap, making them unreadable.

Is there a way to make the x tick locator not place ticks at the 'edge' of the axes, make the labels adjust the placement so they fall inside the axes width, or make them autodetect the collisions? Or is there a better way to avoid the collision of x tick labels when placing axes close together?

EDIT: I updated the code so it reproduces my original manual and limited-adjusted plots, but also includes the answer, for reference

import matplotlib.pyplot as plt
import matplotlib.ticker
import matplotlib
matplotlib.rcParams['xtick.labelsize'] = 5
matplotlib.rcParams['ytick.labelsize'] = 5

def mkplot():
    fig,axs = plt.subplots(1,2,figsize=(2,2),gridspec_kw={'wspace':0},sharey=True)
    axs[0].plot([0.1,0.2,0.3],[0,2,3])
    axs[0].xaxis.set_major_formatter(matplotlib.ticker.PercentFormatter(xmax=1))
    axs[1].plot([3,2,1],[1,2,3])
    axs[1].yaxis.set_tick_params(labelleft=False,size=0)
    return fig,axs

#######################
fig,axs = mkplot()
fig.suptitle('No adjustment')

#######################
fig,axs= mkplot()
axs[0].set_xlim(0.05,0.32)
axs[0].set_xticks([0.1,0.2,0.3])
axs[1].set_xlim(0.7,3.2)
axs[1].set_xticks([1,2,3])
fig.suptitle('Manual limits and ticks')

#######################
fig,axs = mkplot() 
axs[0].get_xticklabels()[-2].set_horizontalalignment('right')
axs[1].get_xticklabels()[+1].set_horizontalalignment('left')
fig.suptitle('Manual alignment')

unadjusted lims and ticks slignement


Solution

  • right, left

    You can manipulate the text of the tick labels, specifically their horizontal alignment.

    Beware that the list of text objects is augmented by two, e.g., for the second axis it is "0", "1", "2", "3", "4".

    import matplotlib.pyplot as plt
    
    fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(2.2, 2),
                                   gridspec_kw={'wspace':0},
                                   sharey=True)
    ax0.plot([0.1, 0.2, 0.3], [0, 2, 3])
    ax1.plot([3, 2, 1], [1, 2, 3])
    
    l0 = ax0.get_xticklabels()
    l0[-2].set_horizontalalignment('right')
    ax0.set_xticklabels(l0)
    
    l1 = ax1.get_xticklabels()
    l1[+1].set_horizontalalignment('left')
    ax1.set_xticklabels(l1)
    
    fig.savefig('Figure_1.png')