Python Matplotlib数据可视化实例:折线图、柱状图与散点图绘制
在 Python 数据分析与展示中,Matplotlib 是最为基石的可视化工具库。无论是探查连续变化规律、横向对比多组离散指标,还是寻找变量间的关联分布,折线图、柱状图与散点图这三类基础图表能够覆盖日常分析中绝大部分的可视化需求。本文将基于统一规范的面向对象接口,结合完整的代码实例,逐一讲解这三类图表的标准绘制流程、参数微调要点与实用避坑技巧。
一、Matplotlib 绘图架构:面向对象接口与状态机接口的取舍
Matplotlib 提供两种完全不同的编写模式:一种是以 plt.plot()、plt.title() 为代表的 pyplot 状态机接口;另一种则是显式创建画布与坐标轴对象的 面向对象(Object-Oriented, OO)接口。理解二者的差异对编写可维护的代码至关重要。
在一致的单子图或简单脚本场景下,状态机接口能够通过少敲两行代码迅速出图。但在需要绘制复杂多子图、精细调整每个坐标轴边距、或者在工程函数中封装绘图逻辑时,状态机接口依赖隐藏的“当前活动坐标轴(Current Axes)”,极易发生属性错位或意外覆盖。面向对象接口通过 fig, ax = plt.subplots() 明确将画布(Figure)与坐标系(Axes)分离开来,所有的绘图动作均明确指向指定的 ax 实例,逻辑高度自洽且便于复用。
二、基础环境准备与中文字体配置
在开始绘图之前,确保 Python 运行环境中已经安装好 Matplotlib 以及常用的科学计算库:
pip install matplotlib numpy pandas
Matplotlib 默认的字体库并不包含中文字符集,若直接绘制带有中文标签或标题的图形,文字位置通常会显示为缺失方块(俗称“豆腐块”),并在终端报出 UserWarning: Glyph ... missing from current font 警告。此外,负号(Minus Sign)也经常被错误渲染成方块。
解决该问题的标准做法是在脚本导入模块后,通过全局参数字典 plt.rcParams 配置适用的中文字体并关闭负号 ASCII 转码:
import matplotlib.pyplot as plt
import numpy as np
# 根据操作系统自动或手动匹配中文字体
# macOS 推荐 'Arial Unicode MS' 或 'PingFang SC',Windows 推荐 'Microsoft YaHei' 或 'SimHei'
plt.rcParams['font.sans-serif'] = ['PingFang SC', 'Microsoft YaHei', 'SimHei', 'sans-serif']
plt.rcParams['axes.unicode_minus'] = False # 确保负号正常显示
三、实例一:折线图(Line Chart)——展示趋势与时序变化
折线图的核心功能在于表现连续变量随另一连续变量(常见为时间、批次或温度)的变化规律。它借助连续线段引导视线,帮助读者快速识别数据的整体走势、波动周期以及极值突变。
1. 核心绘制方法与关键参数
ax.plot(x, y, ...):绘制基本折线。linestyle(或ls):线型,常见为实线'-'、虚线'--'、点划线'-.'。linewidth(或lw):线条宽度,推荐设置在 1.5 到 2.5 之间以兼顾清晰度。marker与markersize:在数据点处标记符号(如圆点'o'、方块's'、三角形'^'),避免读者对数据点真实位置产生误解。color:线条与标记的颜色。label:图例标识,与ax.legend()配合呈现。
2. 完整实战代码:双产品月度销售额趋势对比
import matplotlib.pyplot as plt
import numpy as np
# 1. 准备数据:12 个月份及两款产品的月销售额(单位:万元)
months = [f"{i}月" for i in range(1, 13)]
sales_product_a = [32, 35, 41, 48, 55, 68, 72, 70, 65, 58, 52, 49]
sales_product_b = [20, 22, 28, 30, 38, 42, 45, 50, 56, 62, 71, 80]
# 2. 创建画布与坐标轴
fig, ax = plt.subplots(figsize=(10, 5.5), dpi=100)
# 3. 绘制折线
ax.plot(months, sales_product_a, marker='o', markersize=6,
color='#687D8D', linewidth=2, label='产品 A(传统品类)')
ax.plot(months, sales_product_b, marker='s', markersize=6,
color='#879B88', linewidth=2, linestyle='--', label='产品 B(新兴品类)')
# 4. 细节调整与标注
ax.set_title("2025年度产品 A 与产品 B 月度销售额走势对比", fontsize=15, pad=12, fontweight='bold')
ax.set_xlabel("月份", fontsize=12, labelpad=8)
ax.set_ylabel("销售额(万元)", fontsize=12, labelpad=8)
ax.set_ylim(10, 90)
# 添加浅灰色背景网格,仅保留 y 轴方向网格线以增强读数便利
ax.grid(axis='y', linestyle=':', alpha=0.6, color='#A0AEC0')
# 激活图例
ax.legend(loc='upper left', frameon=True, facecolor='#FFFFFF', edgecolor='#D9D5CC')
# 自动紧凑排版
fig.tight_layout()
# 保存或显示图形
# fig.savefig('line_chart_example.png', dpi=300)
plt.show()
四、实例二:柱状图(Bar Chart)——离散类别对比与分组展示
当需要清晰表达互不重叠的独立分类(如部门名称、品牌分类、地区分布)之间的指标高低时,柱状图是最具信服力且认知负担最低的图表。
1. 核心绘制方法与关键参数
ax.bar(x, height, width, ...):绘制垂直柱状图;若类别名称过长,可换用ax.barh(y, width, height)绘制水平条形图。width:柱体宽度,默认 0.8。多组对比时通常需要收窄(如 0.35)。color与edgecolor:柱体填充色与边框色。ax.bar_label(container, fmt, ...):Matplotlib 3.4+ 引入的快捷标签方法,能免去手动循环标注坐标的繁琐计算。
2. 完整实战代码:多部门季度营收与目标对比(并列柱状图)
import matplotlib.pyplot as plt
import numpy as np
# 1. 准备数据:五个业务线的目标值与实际达成值
departments = ['电商业务', '企业服务', '云基础设施', '数字营销', '创新实验室']
targets = [120, 95, 140, 80, 50]
actuals = [135, 88, 155, 76, 62]
x = np.arange(len(departments)) # 类别位置索引:array([0, 1, 2, 3, 4])
bar_width = 0.36 # 柱条宽度
# 2. 创建画布与坐标轴
fig, ax = plt.subplots(figsize=(10, 5.8), dpi=100)
# 3. 绘制并列柱状图(通过左右偏移 x 坐标避免重叠)
bars_target = ax.bar(x - bar_width/2, targets, width=bar_width,
label='目标营收', color='#B8C4CE', edgecolor='#8A9BA8', linewidth=1)
bars_actual = ax.bar(x + bar_width/2, actuals, width=bar_width,
label='实际营收', color='#879B88', edgecolor='#627563', linewidth=1)
# 4. 在柱顶添加具体数值标签
ax.bar_label(bars_target, padding=3, fontsize=10, color='#4A5568')
ax.bar_label(bars_actual, padding=3, fontsize=10, color='#2D3748', fontweight='bold')
# 5. 坐标轴及标题润色
ax.set_title("各业务部门第四季度目标 vs 实际营收完成情况(单位:万元)", fontsize=15, pad=14, fontweight='bold')
ax.set_ylabel("营收金额(万元)", fontsize=12)
ax.set_xticks(x)
ax.set_xticklabels(departments, fontsize=11)
ax.set_ylim(0, 180) # 基准严格从 0 开始,并留出柱顶文字空间
# 仅显示水平参考网格线
ax.grid(axis='y', linestyle='--', alpha=0.5, color='#CBD5E0')
# 配置图例
ax.legend(loc='upper right', frameon=True, facecolor='#FFFFFF')
fig.tight_layout()
plt.show()
五、实例三:散点图(Scatter Plot)——多维分布与相关性探究
散点图通过在平面直角坐标系中投射离散数据点,主要用于揭示两组连续变量之间是否存在某种相关倾向(如正相关、负相关、非线性相关)或者聚类聚集。与折线图不同,散点图的各点之间没有连线,不假设点与点之间具有顺序连续性。
1. 核心绘制方法与关键参数
ax.scatter(x, y, s=None, c=None, cmap=None, alpha=None, ...):散点图基础方法。s(Size):点的大小。可以传入一个数值使所有点尺寸相同,也可以传入一维数组使各点大小映射第三个数值变量(构建气泡图)。c(Color):点的颜色。可指定单一颜色,也可传入数值数组结合颜色映射表cmap展现第四个连续变量。alpha:透明度(0~1)。在样本密度较高时,适度调低alpha(如 0.6)能让密集的重叠区域通过颜色加深自然呈现,有效避免“数据过度遮挡(Overplotting)”。
2. 完整实战代码:广告投放花费与用户转化多维分析
import matplotlib.pyplot as plt
import numpy as np
# 1. 模拟生成 50 组投放活动数据
np.random.seed(42)
spend = np.random.uniform(20, 200, 50) # 投放花费(千元)
# 转化量与花费呈弱非线性正相关,并伴随随机扰动
conversions = 3.5 * np.sqrt(spend) + np.random.normal(0, 3, 50)
roi = (conversions * 15) / spend # 投资回报率(第四维,用于色彩映射)
audience_scale = np.random.uniform(100, 800, 50) # 触达人群规模(第三维,点面积)
# 2. 创建画布与坐标轴
fig, ax = plt.subplots(figsize=(10, 6), dpi=100)
# 3. 绘制散点图
scatter = ax.scatter(spend, conversions,
s=audience_scale / 2, # 点面积
c=roi, # 映射颜色
cmap='YlGnBu', # 优雅的黄绿蓝调色板
alpha=0.75,
edgecolors='#4A5568',
linewidth=0.8)
# 4. 添加颜色条说明第四维指标
cbar = fig.colorbar(scatter, ax=ax)
cbar.set_label('ROI 指数(产销比)', fontsize=11, labelpad=8)
# 5. 标注与修饰
ax.set_title("广告投放成本与转化量关联性分析(点大小=触达人数)", fontsize=15, pad=14, fontweight='bold')
ax.set_xlabel("投放成本(千元)", fontsize=12)
ax.set_ylabel("获取转化用户数(百人)", fontsize=12)
ax.grid(True, linestyle=':', alpha=0.5, color='#CBD5E0')
fig.tight_layout()
plt.show()
六、三大图表选型与高频参数全景速查
为了帮助读者在日常分析中快速选用恰当的图表类型与接口方法,下表将三种核心图表及其典型应用规则进行横向梳理:
| 图表类型 | 核心接口与调用 | 典型适用数据形态 | 核心视觉编码 | 最容易犯的错误 |
|---|---|---|---|---|
| 折线图 | ax.plot(x, y, ...) |
连续型数值、时间序列、批次变化 | 折线斜率、连线趋势、拐点 | 对无序分类指标乱连线;数据点过于密集未降采样。 |
| 柱状图 | ax.bar(x, height, ...)ax.barh(...) |
离散分类、名单排名、多组指标横向对照 | 柱体高度或长度绝对对比 | Y 轴不从 0 起始夸大微小差异;分组柱体过多重叠拥挤。 |
| 散点图 | ax.scatter(x, y, s, c, ...) |
两组连续数值,需观察关联、分布或聚类 | 点二维坐标、气泡面积、颜色阶调 | 数据重叠未设置透明度;将分类离散变量直接做散点图导致垂直重合。 |
七、常见排错与工程细节建议
在实际使用 Matplotlib 出图过程中,有几个高频发生的典型问题值得格外注意:
- 刻度标签旋转与重叠:当 X 轴类别名称较长或数据点过密时,文字极易相互重叠遮挡。可以通过
ax.tick_params(axis='x', rotation=45)或plt.setp(ax.get_xticklabels(), rotation=45, ha='right')让文字倾斜 45 度并向右对齐。 - 保存图片时边缘标签被截断:调用
fig.savefig("output.png")保存图片时,可能会发现左侧 Y 轴标题或底部 X 轴文字被裁切了一半。除了在绘图末尾调用fig.tight_layout()之外,在保存时添加bbox_inches='tight'参数是彻底消除边缘裁切的最稳妥方案:fig.savefig('figure.png', dpi=300, bbox_inches='tight') - 循环出图时的内存泄漏问题:在后台批量生成上百张图表时,如果只调用
plt.subplots()却不显式关闭,Matplotlib 会一直保留每个 Figure 实例的内存。务必在每张图保存后调用plt.close(fig)显式释放资源。
掌握了折线图、柱状图与散点图的面向对象编写范式后,无论面对何种维度的业务数据,都可以通过自由组合这些基础组件,构建出逻辑严密、排版专业的数据可视化成果。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













