如何将多个Matplotlib饼图合并到单个Figure并设置子图标题?
问题:在单个Figure中生成多个带标题的饼图
现有如下数据列表:
state = [{'success': 17, 'failed': 28}, {'success': 15, 'failed': 22}]
需要为列表中每个字典生成饼图,并将所有饼图放在同一个Figure里,同时根据动态列表pipeline_names为每个饼图设置对应标题:
pipeline_names = ['Pipeline1','Pipeline2']
其中Pipeline1对应第一个饼图标题,Pipeline2对应第二个。
尝试了以下代码,但生成的是两个独立图表而非包含两个饼图的单个Figure:
for k in range(len(state)): fig, axs = plt.subplots(1, 2, figsize=(6, 3)) axs[k].pie(state[k].values(), labels=state[k].keys(), autopct='%.0f%%') axs[k].set_title(p for p in pipeline_names) plt.ylabel('Status in %') plt.xlabel('Pipeline') plt.savefig('Pipeline_Chart%03d.png'%(k))
代码问题分析
- 循环内重复创建Figure:每次循环都执行
fig, axs = plt.subplots(1, 2),导致每次生成新的独立Figure,而非复用同一个。 - 标题设置错误:
set_title(p for p in pipeline_names)传入的是生成器对象,而非对应索引的管道名称。 - 重复保存图片:循环内每次保存单个子图对应的图片,最终得到两张独立图表。
修正后的代码
import matplotlib.pyplot as plt state = [{'success': 17, 'failed': 28}, {'success': 15, 'failed': 22}] pipeline_names = ['Pipeline1','Pipeline2'] # 仅创建一次包含1行2列子图的Figure fig, axs = plt.subplots(1, 2, figsize=(10, 5)) # 同时遍历状态数据和管道名称 for idx, (status_data, pipe_name) in enumerate(zip(state, pipeline_names)): current_ax = axs[idx] # 绘制饼图 current_ax.pie(status_data.values(), labels=status_data.keys(), autopct='%.0f%%') # 设置对应子图的标题 current_ax.set_title(pipe_name) # 饼图无需坐标轴标签,清空避免干扰 current_ax.set_xlabel('') current_ax.set_ylabel('') # 设置Figure全局标题(可选) fig.suptitle('各管道执行状态占比', y=1.02) # 调整子图布局,避免标题重叠 plt.tight_layout() # 保存包含所有饼图的单个Figure plt.savefig('Pipeline_Charts.png') plt.show()
关键修正点
- 将
plt.subplots移至循环外,确保只创建一个Figure和一组子图。 - 使用
zip同时遍历state和pipeline_names,直接获取对应的数据和标题。 - 移除循环内的图片保存操作,仅在最后保存整个Figure。
- 清空饼图的坐标轴标签,优化视觉效果;用
tight_layout()调整布局避免元素重叠。
内容的提问来源于stack exchange,提问作者bikash_sb
相关产品推荐
相关产品推荐

