简体   繁体   中英

How to adjust the axis size in matplotlib?

My goal is to create a hierarchical x-axis with the dates. To do this, I am following the steps of this answer . I have the day on the first x-axis:

import pandas as pd
import numpy as np
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 = plt.figure(num="TEST")
ax1 = fig.add_subplot(1, 1, 1)

ax1.plot(date, data)

ax1.set_xticks(date)
ax1.set_xticklabels(day)
ax1.margins(x=0)

plt.show()

And with the following code block, I generate the month on the second x-axis:

ax2 = ax1.twiny()

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

ax2.set_xticks([0, 2.5, 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']))

This works perfectly on a line plot:

在此处输入图像描述

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

在此处输入图像描述

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.

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])

调整第二个 x 轴的长度

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM