Matplotlib子图与常用图表

Matplotlib子图与常用图表

2026年9月20日·#编程学习/python学习笔记Python/数据分析·1136 字 6 分钟
浏览量加载中...
AI 摘要

用 subplots 在一张画布上创建多个子图,以及折线图、柱状图、饼状图三种常用图表的画法与适用场景

为什么要用子图#

为了能同时展示多个图表、便于图表之间数据的直观对比和分析,更高效地组织复杂的可视化信息,通常会在一个画布上创建多个子图

import matplotlib.pyplot as plt
figure, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 6), dpi=100)
# figure : 画布对象
# axes : 子图数组(里面装着 Axes 对象)
# nrows / ncols : 行数 / 列数 figsize : 画布大小 dpi : 清晰度
axes[0].bar(...) # 左边的子图:柱状图
axes[1].pie(...) # 右边的子图:饼状图

axes 的索引规则#

布局取值方式
nrows=1, ncols=2(一行两列)axes[0]axes[1]
nrows=2, ncols=2(两行两列)axes[0][0]axes[0][1]axes[1][0]axes[1][1]axes[行][列]
Tip

记住 axes[行][列] 就能定位任意子图;写成 axes1 = axes[0][0] 这样起个短名字,后面设置标题就不用重复写下标了。

三种常用图表#

图表方法适用场景
折线图plot(x, y)展示趋势变化(如每年电影数量)
柱状图bar(x, y, width=0.6, color='g')展示数量对比(如各国石油储备)
饼图pie(values, labels=..., autopct='%1.1f%%')展示比例构成(如各国人口占比)

子图上的设置#

在外面用 plt.xxx,在子图上就用 axes.xxx(多一个 set_):

全局写法子图写法
plt.title('...')axes.set_title('...', fontsize=18)
plt.xlabel('...')axes.set_xlabel('...')
plt.ylabel('...')axes.set_ylabel('...')
plt.grid(...)axes.grid(...)

完整示例:柱状图 + 饼图#

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
figure, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 6), dpi=100)
# 图一:柱状图(世界石油储备)
countries = ['中国', '美国', '印度', '加拿大', '伊拉克', '沙特', '伊朗', '英国', '德国']
values = [35, 23, 18, 21, 56, 78, 51, 12, 18]
axes[0].bar(countries, values, width=0.6, color='g')
axes[0].set_title('世界石油储备', fontsize=18)
axes[0].set_xlabel('国家')
axes[0].set_ylabel('石油储备(亿吨)')
axes[0].grid(linestyle='--', alpha=0.3)
# 图二:饼状图(世界人口比例)
countries2 = ['印度', '中国', '美国', '印尼', '巴基斯坦', '其他']
values2 = [14.51, 14.09, 3.4, 2.83, 2.51, 20]
axes[1].pie(values2, labels=countries2, autopct='%1.1f%%')
axes[1].set_title('世界人口比例', fontsize=18)
axes[1].legend(loc='lower center', ncol=3, bbox_to_anchor=(0.5, -0.08))
plt.savefig('data/01.png') # 保存图片
plt.show() # 展示图表
参数作用
autopct='%1.1f%%'饼图上显示百分比(保留 1 位小数)
legend(ncol=3, bbox_to_anchor=(0.5, -0.08))ncol 每行显示几个图例;bbox_to_anchor 控制图例位置
tick_params(axis='x', rotation=90)X 轴标签旋转 90 度(标签太长时用)

小结(复习自测)#

题目答案
如何在画布中创建子图?figure, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 6), dpi=100)
折线图 / 柱状图 / 饼状图分别适合什么?趋势变化 / 数量对比 / 比例构成

相关#

练习题#

一、回忆填空(写完再展开对答案)#

  1. 创建子图:figure, axes = plt.____(nrows=2, ncols=2, figsize=(20, 12), dpi=100)
  2. figure 是 ____ 对象,axes 是 ____ 数组
  3. 一行两列时子图是 axes[0]axes[1];两行两列时是 axes[____][____] 的形式
  4. 折线图用 plot,柱状图用 ____,饼图用 ____
  5. 折线图适合展示 ____,柱状图适合展示 ____,饼图适合展示 ____
  6. 子图上设置标题用 axes.____('...')(比全局写法多一个 set_
  7. 饼图显示百分比用参数 ____='%1.1f%%'
  8. 保存图片用 plt.____('data/01.png')
填空答案(做完再点开)
  1. subplots 2. 画布 / 子图 3. 行、列(如 axes[0][0]) 4. bar / pie 5. 趋势变化 / 数量对比 / 比例构成 6. set_title 7. autopct 8. savefig

二、裸写题#

  • 2-1 一行两列的子图 创建 1 行 2 列的子图,左边画柱状图(自拟 5 个城市的人口),右边画饼图(同样数据看占比),两边都要有标题。

    提示(先自己想,实在想不出再点开)

    一级 · 思路:先建子图拿到 axes,再往 axes[0]、axes[1] 上分别画 二级 · 方法plt.subplots(nrows=1, ncols=2, figsize=(20, 6)) / axes[0].bar(...) / axes[1].pie(...) 三级 · 骨架axes[0].set_title('...', fontsize=18)

  • 2-2 两行两列的布局 改成 2 行 2 列,把两个图放在 axes[0][0]axes[1][1],并给整个画布加标题。

    提示

    一级 · 思路:画布标题是 fig 级别的,不是某个子图的 二级 · 方法fig.suptitle('总标题', x=0.5, y=0.95) / fig.subplots_adjust(hspace=0.4, wspace=0.2) 三级 · 骨架axes[0][0]axes[1][1]

  • 2-3 标签太长怎么办 柱状图的 X 轴是较长的中文名称,画出后标签挤在一起——想办法让它竖着显示。

    提示

    一级 · 思路:旋转刻度标签 二级 · 方法axes.tick_params(axis='x', rotation=90) 三级 · 骨架axis='____' 指定是哪根轴

参考答案(做完再点开)
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
cities = ['北京', '上海', '广州', '深圳', '成都']
pops = [2184, 2487, 1868, 1756, 2126]
# 2-1
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 6), dpi=100)
axes[0].bar(cities, pops, width=0.6, color='g')
axes[0].set_title('城市人口对比', fontsize=18)
axes[0].set_xlabel('城市')
axes[0].set_ylabel('人口(万)')
axes[1].pie(pops, labels=cities, autopct='%1.1f%%')
axes[1].set_title('城市人口占比', fontsize=18)
plt.show()
# 2-2 两行两列 + 画布标题
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(20, 12), dpi=100)
fig.suptitle('城市人口分析', fontsize=23, x=0.5, y=0.95)
fig.subplots_adjust(hspace=0.4, wspace=0.2)
axes[0][0].bar(cities, pops, color='g')
axes[0][0].set_title('人口对比', fontsize=15)
axes[0][0].tick_params(axis='x', rotation=90) # 2-3:标签竖排
axes[1][1].pie(pops, labels=cities, autopct='%1.1f%%')
axes[1][1].set_title('人口占比', fontsize=15)
plt.show()

评论区

[ 标签 ]
# AI37# AI 编程2# AI工具1# Ajax2# Apifox1# AstrBot3# Astro2# CC Switch1# CDN2# Claude Code1# claudecode2# ClaudeCode1# Cloudflare2# CloudFlare2# CloudFlare-ImgBed3# coc3# CSS6# DeepSeek6# deepseek2# DELETE1# Docker1# EdgeOne3# Gist1# git1# GitHub1# hexo-circle-of-friends1# HTML6# HTTP5# ImageManager1# Java23# java13# JavaScript5# JDBC3# JSON2# JUnit1# LangChain25# Logback1# Maven6# Muse Spark1# Mybatis1# MyBatis4# MySQL28# MySql1# NapCat1# Node.js1# obsidian2# Obsidian5# OpenCode4# ORM1# PathVariable1# PicGo1# PyCharm1# Python65# RequestBody1# RequestMapping1# RESTful风格1# skills1# Slf4j1# SpringBoot11# SQL2# Streamlit5# Svelte2# TailwindCSS1# Telegram3# Tlias2# Vercel1# vscode2# Vue7# Waline3# WebDAV1# Web基础6# Web开发6# WinSCP1# YAML1# 三层架构1# 中二宣言1# 书籍1# 使用文档10# 写作1# 函数2# 刷步数1# 前端32# 动态1# 动漫1# 包1# 单词2# 博客7# 博客工作流1# 博客开发2# 参数接收1# 友链1# 反思2# 图床6# 地图1# 备份2# 大模型1# 奇思妙想1# 存储1# 学习方法6# 学校1# 宝塔面板3# 宝宝10# 对象1# 导航栏1# 工具2# 开发1# 开发工具1# 开发规范1# 开心1# 异常处理1# 影视2# 微信1# 性能优化2# 总结1# 想法15# 感受1# 感悟11# 指南1# 提示词工程1# 插件5# 故障排除1# 效率工具2# 教程10# 数据分析9# 数据库27# 数据结构1# 文件操作2# 斩神1# 日常92# 日志框架1# 朋友圈1# 朱元璋1# 模块1# 模板1# 正则表达式2# 测试1# 游戏2# 爬虫7# 生活迁移1# 电影2# 电脑1# 碎碎念1# 视觉识别1# 类1# 类型注解1# 网络基础2# 网络教室1# 羊毛2# 脚本2# 脚本工具1# 自动化2# 蓝奏云1# 订阅推荐2# 记录2# 评论系统1# 词根1# 词缀1# 说说1# 足迹1# 跑步2# 路径参数1# 转载2# 运动1# 部落冲突1# 配置1# 随机图1# 面向对象5# 音乐3# 音标1# 饮食1# 驼峰命名1# 高德地图1
[ 公告 ]

如果你喜欢,那么欢迎来到我的世界!

了解更多
[ 音乐 ]
封面

音乐

暂未播放

0:000:00
暂无歌词
找不到相关结果。
[ contents ]
[ 全部文章 ]