You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何缩小Matplotlib中x轴刻度间距及调整柱状图边距?

问题描述

我已查阅相关资料但其中解答无法解决我的问题。我编写了生成4幅子图的Matplotlib代码如下:

import matplotlib.pyplot as plt
import numpy as np

group_x = [5, 0, 1, 16, 3, 1, 2, 0, 8, 2, 11, 5]
group_y = [8, 10, 6, 0, 0, 5, 12, 0, 14, 2, 1, 7]
group_w = [1, 3, 13, 9, 0, 15, 6, 2, 3, 7, 1, 0]
group_z = [0, 1, 2, 0, 10, 12, 12, 0, 8, 12, 4, 6]
ranges = ['a', '(a, b)', '(b, c)', '(c, d)', '(d, e)', '(e, f)',
          '(f, g)', '(g, h)', '(h, i)', '(i, j)', '(j, k)', 'k']

colors = ['red', 'blue', 'green', 'purple']
participants = ['Group X', 'Group Y', 'Group W', 'Group Z']

fig, axes = plt.subplots(2, 2, figsize=(12, 5))
c = 0
for i, ax_row in enumerate(axes):
    for j, ax in enumerate(ax_row):
        data = [group_x, group_y, group_w, group_z][c]
        ax.text(.5, .9, f'{participants[i]}',
                horizontalalignment='center',
                transform=ax.transAxes)

        bars = ax.bar(ranges, data, color=colors[c], width=0.2)
        ax.set_yticks(np.arange(0, 21, 5))
        ax.set_yticklabels(range(0, 21, 5), fontsize=9)
        ax.set_xticks(np.arange(12))
        ax.set_xticklabels(ranges, rotation=30, ha='right', fontsize=8.5)
        ax.set_xlabel('Characters')
        ax.set_ylabel('Frequency', fontsize=8)
        for bar, score in zip(bars, data):
            ax.text(bar.get_x() + bar.get_width() / 2, bar.get_height(), str(score), ha='center', va='bottom')
        c += 1
plt.tight_layout()
plt.savefig('stackover.png', dpi=600, bbox_inches='tight')
plt.show()

当前生成的图表效果:
图表效果

我希望缩小x轴刻度间的间距,使柱状图与对应x轴刻度紧密相邻,同时让对应'a'的柱状图贴近y轴,对应'k'的柱状图贴近子图右边缘,请问如何修改代码实现这些效果?

解决方案

要实现需求,需调整x轴刻度控制逻辑和柱子宽度,具体修改如下:

核心修改点

  1. 改用数值型x轴位置,替换原字符串标签的自动布局,精确控制刻度间距
  2. 增大柱子宽度,让柱子与刻度更贴合
  3. 设置x轴范围,强制首尾柱子贴紧子图边缘
  4. 修正原代码中标题引用的错误

修改后的完整代码

import matplotlib.pyplot as plt
import numpy as np

group_x = [5, 0, 1, 16, 3, 1, 2, 0, 8, 2, 11, 5]
group_y = [8, 10, 6, 0, 0, 5, 12, 0, 14, 2, 1, 7]
group_w = [1, 3, 13, 9, 0, 15, 6, 2, 3, 7, 1, 0]
group_z = [0, 1, 2, 0, 10, 12, 12, 0, 8, 12, 4, 6]
ranges = ['a', '(a, b)', '(b, c)', '(c, d)', '(d, e)', '(e, f)',
          '(f, g)', '(g, h)', '(h, i)', '(i, j)', '(j, k)', 'k']

colors = ['red', 'blue', 'green', 'purple']
participants = ['Group X', 'Group Y', 'Group W', 'Group Z']

fig, axes = plt.subplots(2, 2, figsize=(12, 5))
c = 0
for i, ax_row in enumerate(axes):
    for j, ax in enumerate(ax_row):
        data = [group_x, group_y, group_w, group_z][c]
        # 修正标题引用错误,用c索引对应分组
        ax.text(.5, .9, f'{participants[c]}',
                horizontalalignment='center',
                transform=ax.transAxes)

        # 生成数值型x轴位置,替代原字符串标签
        x = np.arange(len(ranges))
        # 增大柱子宽度到0.8,缩小刻度间空白
        bars = ax.bar(x, data, color=colors[c], width=0.8)
        ax.set_yticks(np.arange(0, 21, 5))
        ax.set_yticklabels(range(0, 21, 5), fontsize=9)
        # 把刻度精准放在每个柱子的中心位置
        ax.set_xticks(x)
        ax.set_xticklabels(ranges, rotation=30, ha='right', fontsize=8.5)
        ax.set_xlabel('Characters')
        ax.set_ylabel('Frequency', fontsize=8)
        # 设置x轴范围,让首尾柱子贴紧子图边缘
        ax.set_xlim(-0.4, len(x)-0.6)
        for bar, score in zip(bars, data):
            ax.text(bar.get_x() + bar.get_width() / 2, bar.get_height(), str(score), ha='center', va='bottom')
        c += 1
plt.tight_layout()
plt.savefig('stackover.png', dpi=600, bbox_inches='tight')
plt.show()

关键说明

  • 数值型x轴np.arange(len(ranges))让刻度位置完全可控,避免字符串标签的自动间距
  • 柱子宽度设为0.8(最大值为1,代表刻度间无空白),让柱子与刻度紧密对齐
  • ax.set_xlim(-0.4, len(x)-0.6):因柱子宽度为0.8,左边界设为-0.4让第一个柱子左边缘对齐y轴;右边界设为len(x)-0.6让最后一个柱子右边缘对齐子图右边缘
  • 修正了原代码中标题引用的错误,确保每个子图标题对应正确分组

内容的提问来源于stack exchange,提问作者Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 11:05:23