Home > OS >  How to adjust the axis size in matplotlib?
How to adjust the axis size in matplotlib?

Time:12-07

My goal is to create a hierarchical x-axis with the dates. To do this, I am following the steps of this enter image description here

However, when I change the chart type to bar ax1.bar(date, data), the beginning and end ticks of both axis don't match :

enter image description here

Is there a way for both axis to start and end at the same point? Either extending the first axis all the way (regardless overlapping) or adjusting the second axis to match the first axis.

CodePudding user response:

To get both x-axis nicely aligned, it is important that they have the same datalimits (ax2.set_xlim(ax1.get_xlim())). Then, ax2.set_xticks([0, 2.5, 6]) will have the ticks at the center of the first and last bar, and inbetween the third and fourth.

You can use ax2.spines['bottom'].set_bounds([0, 6]) to stop the x-axis at those positions.

If you also want to hide the tick marks of ax1, the standard way is to set their length to zero: ax1.tick_params(axis='x', length=0).

If desired, you can also hide the top and right spines. You'll need to do that for both axes.

from matplotlib import pyplot as plt
import matplotlib.ticker as ticker

date = ['2021-01-29', '2021-01-30', '2021-01-31',
        '2021-02-01', '2021-02-02', '2021-01-03', '2021-01-04']
day = ['29', '30', '31', '01', '02', '03', '04']
data = [5, 4, 3, 9, 7, 8, 2]

fig, ax1 = plt.subplots(num="TEST")

ax1.bar(date, data)

ax1.set_xticks(np.arange(len(date)))
ax1.set_xticklabels(day)
ax1.margins(x=0)
ax1.tick_params(axis='x', length=0)  # hide tick marks

ax2 = ax1.twiny()

ax2.spines['bottom'].set_position(('axes', -0.08))
ax2.tick_params(axis='x', direction='in', which='major')
ax2.xaxis.set_ticks_position('bottom')
ax2.xaxis.set_label_position('bottom')

ax2.set_xlim(ax1.get_xlim()) # same datalimits
ax2.set_xticks([0, 2.5, 6])
ax2.spines['bottom'].set_bounds([0, 6])
ax2.xaxis.set_major_formatter(ticker.NullFormatter())
ax2.xaxis.set_minor_locator(ticker.FixedLocator([1, 4]))
ax2.xaxis.set_minor_formatter(ticker.FixedFormatter(['JAN', 'FEB']))

for ax in (ax1, ax2):
    for spine in ['top', 'right']:
        ax.spines[spine].set_visible(False)

plt.tight_layout()
plt.show()

Instead of shorten, set_bounds() can also extend a bit. For example:

ax2.set_xticks([-0.5, 2.5, 6.5])
ax2.spines['bottom'].set_bounds([-0.5, 6.5])

adjusting the length of a second x-axis

  • Related