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
相关产品推荐
相关产品推荐

