matplotlib prune tick labels

2020-02-12 07:40发布

问题:

I am using GridSpec to plot two plots one below the other without a gap in between with

gs = gridspec.GridSpec(3, 1)
gs.update(hspace=0., wspace=0.)
ax1 = plt.subplot(gs[0:2, 0])
ax2 = plt.subplot(gs[2, 0], sharex=ax1)

which works fine. However, I want to get rid of each subplot's top and bottom tick label. For that I use

nbins = len(ax1.get_yticklabels())
ax1.yaxis.set_major_locator(MaxNLocator(nbins=nbins, prune='both'))
nbins = len(ax2.get_yticklabels())
ax2.yaxis.set_major_locator(MaxNLocator(nbins=nbins, prune='both'))

which in many cases works fine. In some plots, however, one or more of the 4 labels to prune are still there. I looked at e.g. ax1.get_ylim() and noticed that instead of for example the upper limit being 10 (as it is shown in the plot itself), it is actually 10.000000000000002, which I suspect is the reason why it is not pruned. How does that happen and how can I get rid of that?

Here is an example: Note that in the figure the y axis is inverted and no label is pruned, altough it should be. Also note that for some reason the lowest y-label is set to a negative position, which I don't see. The y-tick positions are shown in in axis coordinates in the text within the plots. In the image below, the label at 10.6 should not be there!

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from matplotlib.ticker import MaxNLocator
import numpy as np

x1 = 1
y1 = 10.53839
err1 = 0.00865
x2 = 2
y2 = 9.43045
err2 = 0.00658

plt.clf()
fig = plt.figure(figsize=(6, 6))
gs = gridspec.GridSpec(3, 1)
gs.update(hspace=0., wspace=0.)
ax1 = plt.subplot(gs[0:2, 0])

ax1.errorbar(x1, y1, yerr=err1)
ax1.errorbar(x2, y2, yerr=err2)

ax1.invert_yaxis()

plt.setp(ax1.get_xticklabels(), visible=False)  # Remove x-labels between the plots
plt.xlim(0, 3)

ax2 = plt.subplot(gs[2, 0], sharex=ax1)

nbins = len(ax1.get_yticklabels())
ax1.yaxis.set_major_locator(MaxNLocator(nbins=8, prune='both'))
nbins = len(ax2.get_yticklabels())
ax2.yaxis.set_major_locator(MaxNLocator(nbins=6, prune='both'))

plt.savefig('prune.png')
plt.close()

回答1:

Could it be, that you are looking at the left most label on the x axis of the upper plot? If so, this should do the trick:

ax1.set_xticklabels([])

EDIT: If you use sharex, you have to use this, otherwise the tick labels are removed on both axes.

plt.setp(ax1.get_xticklabels(), visible=False)


回答2:

You can try to use this:

import matplotlib.ticker as mticker

ax2.yaxis.set_major_locator(mticker.MaxNLocator(nbins=7, prune='upper'))

I found the above command only works for the y-axis.

Does someone know how to set up the maximum limits of x-axis tickers' number?