Python matplotlib绘制散点图、柱状图和饼图代码示例
系统介绍使用Python Matplotlib库绘制散点图、柱状图与饼图的完整代码示例与核心参数解析,涵盖面向对象绘图范式、数据映射技巧及常见避坑指南。
在日常数据分析和报表汇报中,散点图、柱状图和饼图是使用频次最高的三种基础统计图表。它们分别承担着观察变量相关性、对比类别数值大小以及展现比例构成的核心任务。本文将直接基于 Python matplotlib 库的面向对象标准接口(fig, ax = plt.subplots()),提供这三类图表规范、可直接运行的代码示例,并解析关键参数的设置逻辑与排错要点。
一、Matplotlib 基础绘图通用生命周期
为了编写结构清晰且便于维护的代码,推荐使用面向对象(Object-Oriented)的绘图模式,而不是直接调用 plt.plot() 等快捷状态机函数。面向对象方式明确将画布对象(Figure)与子图轴对象(Axes)解耦,使得子图布局、坐标轴调整及图元微调更加稳定可控。
在所有绘图代码执行前,必须首先解决中文字符集与负号渲染问题。默认情况下,Matplotlib 不包含完整的中文字体映射,若不配置可能出现方框乱码。通用配置如下:
import matplotlib.pyplot as plt
import numpy as np
# 跨平台中文支持配置
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'PingFang SC', 'sans-serif']
plt.rcParams['axes.unicode_minus'] = False # 确保负号正常显示为减号而不是方块
二、散点图(Scatter Plot)代码示例与参数解析
散点图常用于展现两个连续变量之间的相关性、群集特征或离群点分布。核心函数为 ax.scatter()。除基础的 X、Y 坐标外,还可以利用数据点的大小(s)、颜色(c)、透明度(alpha)映射额外的数据维度。
1. 完整代码示例
import matplotlib.pyplot as plt
import numpy as np
# 设置随机种子以保证结果可复现
np.random.seed(42)
# 模拟 100 组样本数据
x = np.random.randn(100) * 15 + 50 # 模拟特征 A(例如:广告预算)
y = x * 1.8 + np.random.randn(100) * 10 # 模拟特征 B(例如:销售额,具备线性相关特征)
point_size = np.random.uniform(20, 200, 100) # 第三维度:业务规模(映射为散点大小)
color_values = y - x # 第四维度:净收益增量(映射为散点颜色)
# 1. 创建画布与坐标系
fig, ax = plt.subplots(figsize=(8, 5), dpi=100)
# 2. 绘制散点图
scatter = ax.scatter(
x, y,
s=point_size, # 点的面积大小
c=color_values, # 颜色映射序列
cmap='viridis', # 渐变调色板
alpha=0.75, # 透明度,减轻重叠干扰
edgecolors='white', # 散点外边缘颜色
linewidths=0.8 # 边框粗细
)
# 3. 添加颜色条说明与坐标轴标签
cbar = fig.colorbar(scatter, ax=ax)
cbar.set_label('净收益增量指标', fontsize=10)
ax.set_title('广告投入与销售收益散点分布图', fontsize=14, pad=12)
ax.set_xlabel('广告投放预算(万元)', fontsize=11)
ax.set_ylabel('实际销售金额(万元)', fontsize=11)
ax.grid(True, linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()
2. 核心参数与注意事项
s(Size):注意s接收的是散点面积(点平方 points^2)而非半径。若直接将未归一化的原始数值传给s,过大的数值会导致散点铺满画布,过小的数值会看不清。建议使用线性缩放归一化到[20, 300]区间。alpha(透明度):当样本量较多时,散点容易重叠形成黑色色块。设置alpha=0.4~0.7可以清晰识别高密度聚合区域。cmap与fig.colorbar():将一维数值映射为渐变颜色时,需配合fig.colorbar(scatter, ax=ax)显示数值刻度条,否则读者无法判断颜色所代表的具体数值区间。
三、柱状图(Bar Chart)代码示例与参数解析
柱状图用于展示离散分类变量的数值对比。当需要对比多组分类数据(例如不同季度的两类产品销量)时,通常采用并列柱状图或堆叠柱状图。在绘制多组并列柱状图时,必须手动计算每个柱子在 X 轴上的偏移量,以避免相互遮挡。
1. 完整代码示例(多组并列柱状图)
import matplotlib.pyplot as plt
import numpy as np
# 分类标签与两组指标数据
categories = ['第一季度', '第二季度', '第三季度', '第四季度']
sales_product_a = [120, 145, 175, 210]
sales_product_b = [95, 130, 160, 185]
# X 轴基准刻度位置与柱体宽度
x_indices = np.arange(len(categories))
bar_width = 0.35 # 单个柱子的宽度
# 1. 创建画布与坐标系
fig, ax = plt.subplots(figsize=(8, 5), dpi=100)
# 2. 绘制并列柱状图(通过偏移 x_indices 实现并排)
rects1 = ax.bar(x_indices - bar_width/2, sales_product_a, width=bar_width,
label='产品 A', color='#83ADD0', edgecolor='#142537', linewidth=0.8)
rects2 = ax.bar(x_indices + bar_width/2, sales_product_b, width=bar_width,
label='产品 B', color='#77B9AE', edgecolor='#142537', linewidth=0.8)
# 3. 标注数值标签(Matplotlib 3.4+ 内置函数)
ax.bar_label(rects1, padding=3, fontsize=9)
ax.bar_label(rects2, padding=3, fontsize=9)
# 4. 配置坐标轴文本、刻度与图例
ax.set_title('2025年度各季度产品销售对比', fontsize=14, pad=12)
ax.set_xlabel('财年季度', fontsize=11)
ax.set_ylabel('销售额(万元)', fontsize=11)
ax.set_xticks(x_indices)
ax.set_xticklabels(categories)
ax.set_ylim(0, 250)
ax.legend(frameon=True, facecolor='#ffffff', edgecolor='#cbd5e1')
ax.grid(axis='y', linestyle=':', alpha=0.6)
plt.tight_layout()
plt.show()
2. 核心参数与注意事项
- X 轴偏移量计算:若有
N组数据,单组柱宽为w,则各组中心点依次为x + (i - (N-1)/2) * w。若不偏移直接调用多次ax.bar(),后绘制的柱子会直接覆盖在前面的柱子上。 ax.bar_label():相比过去使用for循环和ax.text()手动排版,内置的ax.bar_label()能自动适应柱高并处理垂直对齐,padding参数可微调文字与柱顶的间距。- 横向柱状图(
ax.barh):当类别名称较长(如部门全称、技术栈名称)时,纵向柱状图的 X 轴标签容易发生交叠,此时改用ax.barh(y, width)可以极大提升可读性。
四、饼图(Pie Chart)代码示例与参数解析
饼图用于显示各组成部分在总体中的百分比份额。饼图适用于分类项较少(通常不超过 5~7 项)且总和具备明确“整体(100%)”语义的场景。若分类过多,应优先选用横向柱状图。
1. 完整代码示例(分离切片与环形图样式)
import matplotlib.pyplot as plt
# 数据与标签定义
labels = ['智能硬件', '企业软件', '云端服务', '咨询服务', '其他业务']
sizes = [35, 25, 20, 12, 8]
colors = ['#83ADD0', '#77B9AE', '#5B8FB9', '#E09F67', '#A0AEC0']
# 突出显示占比最大的项(智能硬件)
explode = (0.06, 0, 0, 0, 0)
# 1. 创建画布与坐标系
fig, ax = plt.subplots(figsize=(7, 6), dpi=100)
# 2. 绘制饼图
wedges, texts, autotexts = ax.pie(
sizes,
explode=explode, # 切片分离距离
labels=labels, # 外部文本标签
colors=colors, # 各切片颜色
autopct='%1.1f%%', # 内部百分比格式化字符串
startangle=140, # 起始角度(逆时针旋转)
pctdistance=0.75, # 百分比数字距离圆心的距离比率
wedgeprops=dict(width=0.6, edgecolor='white', linewidth=1.5) # 环形图空心参数
)
# 3. 增强百分比文字样式
for autotext in autotexts:
autotext.set_color('#142537')
autotext.set_fontsize(10)
autotext.set_weight('bold')
for text in texts:
text.set_fontsize(11)
# 4. 强制正圆比例与标题
ax.set_title('2025年度核心业务营收占比分布', fontsize=14, pad=15)
ax.axis('equal') # 确保长宽比一致,避免椭圆畸变
plt.tight_layout()
plt.show()
2. 核心参数与注意事项
ax.axis('equal'):必须显式调用,保证 X 轴和 Y 轴比例尺完全相同,防止因画布长宽比不同而使饼图被拉伸为椭圆。wedgeprops=dict(width=...):通过设置切片环宽,可直接将实心饼图转化为甜甜圈图(Donut Chart),中心空白区域更透气,也可用于放置核心汇总指标文字。autopct格式化:'%1.1f%%'表示保留一位小数的浮点数并追加百分号;若需整数百分比可写为'%d%%'。
五、图表选型决策与特征对比
正确选型是有效传达数据信息的前提。散点图、柱状图和饼图在数据维度、类别容量和信息承载重点上各有侧重:
六、Matplotlib 核心对象层级与图表组件映射
深入理解 Matplotlib 的组件树结构,有助于在调用微调方法时快速定位对象属性。顶层是 Figure,其下承载一个或多个 Axes,而每个 Axes 内部管理着专属的标题、刻度、轴线(Spines)以及具体的图元(Artist):
七、综合应用:单画布组合三种图表
在实际汇报仪表盘中,经常需要在一个 Figure 窗口中并行展示这三类图表。通过 plt.subplots(1, 3, figsize=(18, 5)),我们可以将散点图、柱状图与饼图横向排布,形成统一风格的数据看板:
import matplotlib.pyplot as plt
import numpy as np
# 1. 设置中文与负号环境
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'PingFang SC', 'sans-serif']
plt.rcParams['axes.unicode_minus'] = False
# 2. 模拟三组业务数据
# 散点数据:用户停留时长 vs 消费金额
np.random.seed(101)
stay_minutes = np.random.uniform(5, 60, 60)
spend_amount = stay_minutes * 12 + np.random.normal(0, 50, 60)
# 柱状数据:各渠道获客数量
channels = ['搜索引流', '社交推广', '邮件召回', '信息流']
customer_counts = [4200, 3100, 1850, 2600]
# 饼图数据:各终端活跃设备占比
devices = ['iOS', 'Android', '桌面端', '小程序']
device_shares = [42, 38, 12, 8]
# 3. 创建 1 行 3 列的子图画布
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(16, 5), dpi=100)
# --- 子图 1:散点图 ---
ax1.scatter(stay_minutes, spend_amount, color='#83ADD0', edgecolors='#142537', alpha=0.8, s=45)
ax1.set_title('用户在线时长与消费关联散点', fontsize=12)
ax1.set_xlabel('停留时长 (分钟)')
ax1.set_ylabel('消费金额 (元)')
ax1.grid(True, linestyle=':', alpha=0.5)
# --- 子图 2:柱状图 ---
bars = ax2.bar(channels, customer_counts, color='#77B9AE', width=0.5, edgecolor='#142537')
ax2.bar_label(bars, padding=3, fontsize=9)
ax2.set_title('各渠道新客增长对比', fontsize=12)
ax2.set_xlabel('推广渠道')
ax2.set_ylabel('用户数 (人)')
ax2.set_ylim(0, 5000)
ax2.grid(axis='y', linestyle=':', alpha=0.5)
# --- 子图 3:饼图 ---
ax3.pie(
device_shares,
labels=devices,
colors=['#83ADD0', '#77B9AE', '#5B8FB9', '#E09F67'],
autopct='%1.1f%%',
startangle=90,
wedgeprops=dict(width=0.6, edgecolor='white')
)
ax3.set_title('活跃终端分布占比', fontsize=12)
ax3.axis('equal')
# 4. 全局紧凑排版与展示
plt.tight_layout()
plt.show()
八、常见问题与避坑清单
在初次编写 Matplotlib 代码时,开发者容易在字体渲染、重叠计算和比例拉伸上遇到细节阻碍。以下整理了四类高频排错方案:
fig, ax = plt.subplots() 规范建立画布,并在脚本初始化阶段完成中文环境适配,即可高效稳定地产出符合出版与报告质量的统计图表。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













