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

Matplotlib绘制柱状图时如何将图例放在图外且不被截断

问题描述

参考将图例放置在绘图区域外的方法绘制柱状图时,出现图例被截断的问题;尝试手动调整坐标轴位置的方案后,又出现刻度、标题丢失,图表仅占据画布一半空间的显示异常。

第一次尝试代码

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1,25)
fig = plt.figure()
legend_array = ["one","two"]
hours_count = [0, 4, 5, 4, 3, 2, 1, 4, 6, 4, 3, 2, 1, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0]
plt.bar(x - 0.5, hours_count, 0.5)
plt.bar(x, hours_count, 0.5)
plt.xlabel("count")
plt.ylabel("high priority")
plt.xticks(x, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24])
plt.legend(labels = legend_array,loc='center left', bbox_to_anchor=(1, 0.5))
plt.title("bargraph of high priority errors")
plt.savefig('test.jpg')

运行后图例被截断,效果如下:
图例被截断的柱状图

第二次尝试代码

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1,25)
fig = plt.figure()
legend_array = ["one","two"]
ax = fig.add_axes([0,0,1,1])
hours_count = [0, 4, 5, 4, 3, 2, 1, 4, 6, 4, 3, 2, 1, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0]
ax.bar(x - 0.5, hours_count, 0.5)
ax.bar(x, hours_count, 0.5)
plt.xlabel("count")
plt.ylabel("high priority")
plt.xticks(x, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24])
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.6, box.height])
ax.legend(labels = legend_array,loc='center left', bbox_to_anchor=(1, 0.5))
plt.title("bargraph of high priority errors")
plt.savefig('test.jpg')

运行后图表缺失刻度、标题,仅占据画布一半空间,效果如下:
显示异常的柱状图

解决方案

两种可直接复用的修复方案:

方案1:保存时自动适配画布边界

无需手动调整坐标轴尺寸,仅需在savefig()中传入参数bbox_inches='tight',保存环节会自动计算所有元素(包括外置图例)的边界,自动调整画布范围避免内容截断。
对应修改后的可运行代码:

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1,25)
fig = plt.figure()
legend_array = ["one","two"]
hours_count = [0, 4, 5, 4, 3, 2, 1, 4, 6, 4, 3, 2, 1, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0]
plt.bar(x - 0.5, hours_count, 0.5)
plt.bar(x, hours_count, 0.5)
plt.xlabel("count")
plt.ylabel("high priority")
plt.xticks(x, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24])
plt.legend(labels = legend_array,loc='center left', bbox_to_anchor=(1, 0.5))
plt.title("bargraph of high priority errors")
plt.savefig('test.jpg', bbox_inches='tight')

方案2:创建画布时预留图例空间

第二次代码显示异常的核心原因是fig.add_axes([0,0,1,1])将坐标轴区域直接铺满了整个画布,没有给刻度标签、标题预留默认边距,手动缩窄坐标轴宽度后就会出现内容只占半幅、元素缺失的问题。
使用plt.subplots()规范创建坐标轴,配合tight_layout()提前给右侧图例预留空间即可,注意绘图时尽量统一使用ax开头的面向对象接口,避免混用plt系列接口导致的元素匹配异常:

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1,25)
fig, ax = plt.subplots()
legend_array = ["one","two"]
hours_count = [0, 4, 5, 4, 3, 2, 1, 4, 6, 4, 3, 2, 1, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0]
ax.bar(x - 0.5, hours_count, 0.5)
ax.bar(x, hours_count, 0.5)
ax.set_xlabel("count")
ax.set_ylabel("high priority")
ax.set_xticks(x, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24])
ax.legend(labels = legend_array,loc='center left', bbox_to_anchor=(1, 0.5))
ax.set_title("bargraph of high priority errors")
# 给右侧图例预留15%的画布宽度
plt.tight_layout(rect=[0, 0, 0.85, 1])
plt.savefig('test.jpg')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 21:18:15