Python商务数据分析——Matplotlib 数据可视化学习笔记
一、Matplotlib 基础认知
1.1 库功能与定位
- 核心作用:将数据可视化展示,提升数据直观性与说服力
- 应用场景:绘制折线图、饼图、柱状图等 2D/3D 图表
- 双接口模式:
-
- MATLAB 风格:通过pyplot函数快速绘图(自动管理图形对象)
-
- 面向对象:显式创建Figure和Axes对象(适合复杂绘图)
1.2 核心对象架构
- 容器类:图 (Figure)、坐标系 (Axes)、坐标轴 (Axis)、刻度 (Tick)
- 基础类:线条、文本、图例、网格、标题等
1.3 环境搭建
# 安装命令
pip install matplotlib
# 验证安装
import matplotlib.pyplot as plt
print(plt.__name__) # 输出:matplotlib.pyplot
二、Pyplot 绘图基础
2.1 核心函数速查表
功能分类 | 常用函数 | 说明 |
图形控制 | figure() | 创建空白图形 |
show() | 显示图形 | |
savefig() | 保存图形到文件 | |
子图管理 | subplot(nrows, ncols, index) | 在网格中添加子图 |
subplots(rows, cols) | 创建子图矩阵 | |
subplot2grid(shape, loc) | 非等分网格布局 | |
元素设置 | xlabel()/ylabel() | 设置坐标轴标签 |
title()/suptitle() | 设置子图 / 总图标题 | |
legend() | 添加图例 | |
绘图函数 | plot() | 绘制折线图 |
bar()/hist() | 绘制柱状图 / 直方图 | |
scatter()/pie() | 绘制散点图 / 饼图 |
2.2 图形与子图操作
2.2.1 基础图形创建
# 创建8x4英寸、120dpi、深灰色背景的图形
plt.figure(figsize=(8, 4), dpi=120, facecolor='darkgray')
2.2.2 网格子图布局
# 方法1:subplot直接创建
plt.subplot(2, 2, 1) # 2行2列第1个子图
plt.subplot(2, 2, 2, polar=True) # 极坐标子图
# 方法2:subplots批量创建
fig, ax = plt.subplots(2, 2)
ax[0, 0].bar(['C', 'C++', 'Java'], [12, 34, 45], color='r')
2.2.3 灵活子图布局
# 非等分网格(3x3布局)
plt.subplot2grid((3, 3), (0, 0), colspan=2) # 占据第1行前2列
plt.subplot2grid((3, 3), (1, 0), rowspan=2, colspan=2) # 占据第2-3行前2列
plt.subplot2grid((3, 3), (0, 2), rowspan=3) # 占据第1-3行第3列
plt.tight_layout() # 自动调整子图间距
三、可视化样式配置
3.1 绘图属性设置
3.1.1 颜色方案
- 字符表示:'b'(蓝)、'g'(绿)、'r'(红)、'k'(黑)
- RGB 表示:'#008000'(绿色)、'#FF5733'(橙色)
- 灰度值:'0.8'(浅灰)、'0.2'(深灰)
3.1.2 线条样式
符号 | 样式 | 示例 |
'-' | 实线 | plt.plot(x, y, '-') |
'--' | 虚线 | plt.plot(x, y, '--') |
'-.' | 点划线 | plt.plot(x, y, '-.' |
':' | 点线 | plt.plot(x, y, ':') |
3.1.3 标记符号
# 常用标记示例
plt.plot(x, y, marker='o') # 圆圈
plt.scatter(x, y, marker='^') # 上三角
plt.plot(x, y, marker='s') # 正方形
plt.scatter(x, y, marker='*') # 星形
3.2 中文显示方案
# 方案1:全局字体设置
plt.rcParams['font.sans-serif'] = ['SimHei'] # 黑体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 方案2:局部字体设置
plt.xticks(fontproperties='Times New Roman', size=10)
plt.title('标题', fontproperties='SimSun') # 宋体标题
四、2D 图表实战
4.1 折线图系列
4.1.1 单序列折线图
import pandas as pd
# 数据读取与处理
df = pd.read_excel('user_analysis.xlsx')
df.dropna(axis=0) # 移除空值行
# 绘图核心代码
plt.plot(df['时间'], df['新关注人数'])
plt.title('公众号每日新增用户数')
plt.xlabel('日期')
plt.ylabel('新增人数')
plt.xticks(rotation=45) # 倾斜x轴标签防重叠
plt.show()
4.1.2 多序列对比图
# 绘制双序列折线图
plt.plot(df['新关注人数'],
marker='o', markersize=5, markerfacecolor='mediumpurple')
plt.plot(df['取消关注人数'],
marker='o', markersize=5, markerfacecolor='orangered')
# 图例与标签设置
plt.legend(['新关注人数', '取消关注人数'], loc='upper center')
plt.xlabel('日期')
plt.ylabel('人数')
4.1.3 堆积折线图
df = pd.read_excel('mobile_phone.xlsx')
# 绘制堆积效果
plt.stackplot(df['品牌'], df['6月'], df['7月'], df['8月'], df['9月'])
# 图表美化
plt.legend(['6月销量', '7月销量', '8月销量', '9月销量'])
plt.title('手机品牌销量趋势堆积图')
plt.ylim(0, 1500) # 设置y轴范围
4.2 散点图应用
4.2.1 基础散点图
# 样本数据
age = [34, 40, 37, 30, 44, 36, 32, 26, 32, 36]
income = [350, 450, 169, 189, 183, 80, 166, 120, 75, 40]
sales = [123, 114, 135, 139, 117, 121, 133, 140, 133, 133]
# 绘制带气泡大小的散点图
plt.scatter(age, sales,
c=np.random.randint(0, 50, 10), # 随机颜色
marker='o', alpha=0.9, # 透明度
edgecolors='red', linewidths=0.3, # 边框样式
s=income) # 气泡大小与收入正相关
4.2.2 分组散点图
df = pd.read_excel('next_budget.xlsx')
men = df[df['gender']=='男性']
women = df[df['gender']=='女性']
# 分组绘制
plt.scatter(men['age'], men['next_budget'],
s=35, c='steelblue', label='男性')
plt.scatter(women['age'], women['next_budget'],
s=35, c='red', label='女性')
# 标签与图例
plt.legend()
plt.title('年龄与购车预算分布')
4.3 柱状图系列
4.3.1 并列柱状图
import numpy as np
x = np.arange(4)
y1 = np.random.randint(20, 50, 4) # 销售A组数据
y2 = np.random.randint(20, 50, 4) # 销售B组数据
# 并列绘制(偏移0.1防止重叠)
plt.bar(x-0.1, y1, width=0.2, label='销售A组')
plt.bar(x+0.1, y2, width=0.2, label='销售B组')
# 刻度与标签
plt.xticks(x, ['Q1', 'Q2', 'Q3', 'Q4'])
plt.legend()
4.3.2 堆积柱状图
x = np.arange(4)
y1 = np.random.randint(20, 50, 4) # 底层数据
y2 = np.random.randint(10, 60, 4) # 堆叠数据
# 堆积实现(bottom参数指定底层数据)
plt.bar(x, y1, width=0.4, label='销售A组')
plt.bar(x, y2, width=0.4, bottom=y1, label='销售B组')
# 图表设置
plt.legend(loc='lower right')
plt.title('季度销售额堆积图')
4.4 饼图与环形图
4.4.1 标准饼图
data = np.random.randint(100, 500, 7) # 随机销售额数据
labels = ["裙子", "毛衣", "牛仔裤", "T恤", "袜子", "配件", "短裤"]
# 绘制带百分比的饼图
plt.pie(data,
autopct='%.1f%%', # 显示百分比
explode=[0.05, 0, 0.1, 0, 0, 0, 0], # 突出显示部分区域
colors=np.random.rand(7, 3), # 随机颜色
startangle=90) # 起始角度
plt.title('服装销售额占比分析')
plt.legend(labels)
4.4.2 环形图实现
# 方案1:饼图改造法
fig, ax = plt.subplots(figsize=(6, 6))
ax.pie([87, 13],
wedgeprops={'width':0.3}, # 控制环宽(0.3表示内径70%)
startangle=90,
colors=['#5DADE2', '#515A5A'])
# 中心文本标注
plt.text(0, 0, "87%", ha='center', va='center', fontsize=42)
plt.title('全球通电率统计')
五、高级可视化图表
5.1 热力图
import numpy as np
# 生成6x5随机数据矩阵
data = np.random.randint(70, 100, (6, 5))
# 绘制热力图
plt.imshow(data, cmap='coolwarm') # 冷暖色调映射
# 坐标轴标签设置
plt.xticks(range(5), ["A指标", "B指标", "C指标", "D指标", "E指标"])
plt.yticks(range(6), [f'产品{i+1}' for i in range(6)])
# 添加颜色条
plt.colorbar()
plt.title('6个产品的五个指标热力图')
5.2 雷达图
import numpy as np
# 地区与指标数据
province = ["湖北", "广东", "湖南", "江西", "云南"]
index1 = [4.5, 4.9, 3.9, 2.8, 2.6, 4.5] # 首尾重复以闭合
index2 = [4.9, 4.7, 4.5, 3.9, 3.8, 4.9]
# 极坐标设置
plt.subplot(polar=True)
theta = np.linspace(0, 2*np.pi, len(index1)) # 圆周等分
# 绘制双序列雷达图
plt.plot(theta, index1)
plt.fill(theta, index1, 'm', alpha=0.1) # 填充区域
plt.plot(theta, index2)
# 图例与标题
plt.legend(['产品1', '产品2'], loc='best')
plt.title('区域产品竞争力雷达图')
5.3 箱线图
import numpy as np
# 生成含离群点的数据
data = np.random.randint(0, 100, 47)
data = np.append(data, [160, 200, -50]) # 添加离群点
# 绘制箱线图
plt.boxplot(data,
whis=1.5, # 离群点判定阈值
showmeans=True, # 显示均值
notch=True) # 凹口显示
# 坐标轴设置
plt.ylim([-100, 250])
plt.title('数据分布箱线图')
plt.xticks([1], ['测试数据'])
六、3D 图形绘制
6.1 3D 散点图
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d') # 创建3D坐标系
# 生成三组随机数据
x = np.random.rand(100)
y = np.random.rand(100)
z = np.random.rand(100)
# 绘制散点图
ax.scatter(x, y, z, marker='o', color='red')
# 坐标轴标签
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
6.2 3D 柱状图
import numpy as np
x = np.arange(8) # X轴坐标
layers = 5 # 柱状图层数
# 生成层叠数据
np.random.seed(10)
heights = np.random.randint(1, 5, (layers, 8)).cumsum(axis=0)
# 3D绘图
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')
# 分层绘制柱状图
for layer_idx in range(layers):
ax.bar3d(x, layer_idx*10, np.zeros(8),
dx=0.7, dy=8, dz=heights[layer_idx],
color=plt.cm.viridis(layer_idx/layers))
6.3 3D 曲面图
import numpy as np
from matplotlib import cm
# 生成网格数据
X = np.arange(-10, 10, 0.05)
Y = np.arange(-10, 10, 0.05)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R) # 曲面函数
# 3D曲面绘制
fig = plt.figure()
ax = plt.axes(projection='3d')
surf = ax.plot_surface(X, Y, Z,
cmap=cm.cool, # 颜色映射
shade=True,
linewidth=0)
# 颜色条与坐标轴设置
fig.colorbar(surf, shrink=0.5, aspect=5)
ax.set_zlim(-1, 1)
七、词云图绘制
7.1 基础词云
from wordcloud import WordCloud
# 读取文本
text = open("speak.txt", encoding="gbk").read()
# 生成词云
wc = WordCloud(
background_color="white",
width=1000,
height=660
).generate(text)
# 显示词云
plt.imshow(wc, interpolation='bilinear')
plt.axis("off")
7.2 中文词云(含分词)
import jieba
# 读取中文文本
text = open("党的二十大报告.txt", encoding="gbk").read()
# 文本预处理
text = re.sub(r'[,。!?、()“”\n]', '', text) # 去除标点
words = jieba.cut(text) # 中文分词
# 去除停用词
stopwords = set(['的', '和', '在', '是', '了'])
filtered_words = [word for word in words if word not in stopwords]
text = ' '.join(filtered_words)
# 生成词云
wc = WordCloud(font_path='SIMLI.TTF').generate(text)
7.3 蒙版词云
from PIL import Image
import numpy as np
# 读取蒙版图片
mask = np.array(Image.opge.open("mask.png"))
# 生成带蒙版的词云
wc = WordCloud(
mask=mask,
font_path='SIMLI.TTF',
mode="RGBA",
background_color=None
).generate(text)
# 从蒙版提取颜色
from wordcloud import ImageColorGenerator
image_colors = ImageColorGenerator(mask)
wc.recolor(color_func=image_colors)