智能助教

Matplotlib数据可视化:基本图表绘制¶

教学目标¶

本课程旨在教授如何使用Matplotlib绘制基本图表,包括折线图、柱状图和散点图。课程将结合实际案例,帮助学生将抽象数据转化为直观可视化结果。

1. Matplotlib基础讲解¶

1.1 什么是数据可视化?¶

核心概念:数据可视化是将抽象数据通过图形化手段呈现的过程,帮助人们更直观地理解数据特征和规律。

意义:

  • 历史研究:展示人口变迁、经济发展趋势
  • 社会学:呈现调查统计数据
  • 心理学:可视化实验结果
  • 文学研究:文本数据分析展示

1.2 Matplotlib简介¶

定义:Matplotlib是Python中最基础、最常用的数据可视化库,可以创建各种静态、动态和交互式的图表。

特点:

  • 类似MATLAB的绘图接口,学习曲线平缓
  • 高度可定制化
  • 支持多种输出格式
  • 与NumPy、Pandas等科学计算库完美兼容

1.3 安装¶

  • 方法一

pip install matplotlib

  • 方法二 快速安装

pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple

1.4 基本绘图流程讲解¶

任何Matplotlib图表都遵循以下基本流程:

  1. 准备数据
  2. 创建画布(figure)
  3. 绘制图表
  4. 添加标题、标签等修饰
  5. 显示或保存图表
In [2]:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统
# 或['Arial Unicode MS']  # Mac系统
plt.rcParams['axes.unicode_minus'] = False
# # 准备数据
x = [1, 2, 3, 4]
y = [10, 15, 13, 17]

# 创建画布
plt.figure(figsize=(8,5))

# 绘制图表
plt.plot(x, y)

# 添加修饰
plt.title("示例图表")
plt.xlabel("X轴标签")
plt.ylabel("Y轴标签")

# 显示图表
plt.show()

2. 折线图 (Line Plot) 详解¶

2.1 折线图适用场景¶

显示数据随时间变化的趋势。

最佳使用时机:

  • 显示数据随时间的变化趋势
  • 比较多个序列的变化规律

  • 展示连续数据的波动情况

案例:

  • 年度GDP增长趋势

  • 人口出生率变化

  • 图书出版数量变化

  • 大学生就业率变化

2.2 代码逐行解析¶

In [3]:
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统
# 或['Arial Unicode MS']  # Mac系统
plt.rcParams['axes.unicode_minus'] = False
# 创建数据
years = np.arange(2010, 2021)  # 使用NumPy生成2010-2020的年份序列
enrollment_rates = [56.7, 58.2, 60.1, 62.3, 64.5, 66.8, 69.2, 71.5, 73.8, 75.9, 77.8]  # 对应年份的录取率
# 创建折线图
plt.figure(figsize=(10, 6))  # 设置图形大小(宽10英寸,高6英寸)
plt.plot(
    years,                   # X轴数据
    enrollment_rates,        # Y轴数据
    marker='o',              # 数据点标记为圆形
    color='b',               # 线条颜色为蓝色
    linestyle='-',           # 实线样式
    linewidth=2              # 线宽为2磅
)
# 添加标题和标签
plt.title('2010-2020年中国高等教育录取率变化趋势', fontsize=16)
plt.xlabel('年份', fontsize=12)
plt.ylabel('录取率(%)', fontsize=12)
# 添加网格线
plt.grid(
    True,                   # 显示网格
    linestyle='--',         # 虚线样式
    alpha=0.7               # 透明度70%
)
# 显示图表
plt.show()

2.3 关键参数讲解¶

  • marker:数据点标记样式(o圆形,s方形,^三角形等)

  • color:支持颜色名称('b'=blue)、十六进制值('#FF5733')或RGB元组

  • linestyle:线条样式(-实线,--虚线,:点线等)

  • linewidth:线条粗细(以磅为单位)

2.4 练习¶

任务:绘制过去10年某国家/地区GDP增长率的折线图

思考题:

  • 如果数据点很多,是否还需要marker?为什么?

  • 如何在同一图表中绘制多条折线进行比较?

  • 当X轴标签重叠时该如何处理?

3. 柱状图 (Bar Chart) 详解¶

3.1 柱状图适用场景¶

最佳使用时机:

  • 比较不同类别间的数值差异

  • 显示离散数据的分布情况

  • 展示部分与整体的关系

案例:

  • 不同专业学生人数对比

  • 各地区文化遗产数量

  • 各出版社学术著作出版量

  • 不同年龄段阅读习惯调查

3.2 代码逐行解析¶

In [4]:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统
# 或['Arial Unicode MS']  # Mac系统
plt.rcParams['axes.unicode_minus'] = False

# 创建数据
majors = ['文学', '历史', '哲学', '社会学', '心理学']
students = [320, 180, 150, 240, 210]

# 创建柱状图
plt.figure(figsize=(10, 6))
bars = plt.bar(
    majors,                 # X轴类别
    students,               # 柱体高度
    color=['#4C72B0', '#55A868', '#C44E52', '#8172B2', '#CCB974']  # 自定义颜色
)

# 添加数值标签
for bar in bars:
    height = bar.get_height()  # 获取每个柱体的高度
    plt.text(
        bar.get_x() + bar.get_width()/2.,  # 文本X位置(柱体中心)
        height,                            # 文本Y位置
        f'{height}',                      # 显示数值
        ha='center',                      # 水平居中
        va='bottom'                       # 垂直底部对齐
    )

# 添加标题和标签
plt.title('各专业学生人数分布', fontsize=16)
plt.xlabel('专业', fontsize=12)
plt.ylabel('学生人数', fontsize=12)
Out[4]:
Text(0, 0.5, '学生人数')

3.3 关键参数讲解¶

  • width:控制柱体宽度(默认0.8)

  • align:对齐方式('center'或'edge')

  • alpha:透明度(0-1之间)

  • edgecolor:柱体边框颜色

3.4 练习¶

任务:绘制某城市不同区域图书馆数量的柱状图(询问大模型)

思考题:

  • 当类别名称很长时,如何避免X轴标签重叠?

  • 如何绘制堆叠柱状图展示更多维度信息?

  • 水平柱状图在什么情况下更适合使用?

4. 散点图 (Scatter Plot) 详解¶

4.1 散点图适用场景¶

最佳使用时机:

  • 展示两个变量之间的相关性

  • 发现数据中的聚类或异常值

  • 显示数据分布密度

案例:

  • 阅读时间与成绩关系

  • 收入水平与文化消费关系

  • 城市人口与公共设施数量关系

  • 社交媒体使用与幸福感关系

4.2 代码逐行解析¶

In [5]:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统
# 或['Arial Unicode MS']  # Mac系统
plt.rcParams['axes.unicode_minus'] = False

# 创建模拟数据
np.random.seed(42)  # 设置随机种子确保可重复性
reading_hours = np.random.normal(10, 3, 100)  # 生成100个正态分布的阅读时间数据
exam_scores = 50 + 2*reading_hours + np.random.normal(0, 5, 100)  # 生成与阅读时间相关的成绩数据

# 创建散点图
plt.figure(figsize=(10, 6))
plt.scatter(
    reading_hours,         # X轴数据
    exam_scores,           # Y轴数据
    color='green',         # 点颜色
    alpha=0.6,            # 透明度
    edgecolors='w'        # 点边缘颜色
)
# 添加趋势线
z = np.polyfit(reading_hours, exam_scores, 1)  # 一元线性拟合
p = np.poly1d(z)                              # 生成拟合函数
plt.plot(reading_hours, p(reading_hours), "r--")  # 绘制红色虚线趋势线
# 添加标题和标签
plt.title('每周阅读时间与考试成绩关系', fontsize=16)
plt.xlabel('每周阅读时间(小时)', fontsize=12)
plt.ylabel('考试成绩(分)', fontsize=12)
plt.grid(True, linestyle='--', alpha=0.3)  # 添加半透明虚线网格

4.3 关键参数讲解¶

  • s:控制点的大小

  • c:可以传入数组实现颜色映射

  • marker:点的形状(默认圆形)

  • cmap:颜色映射方案

4.4 练习¶

任务:绘制社交媒体使用时间与幸福指数关系的散点图

思考题:

  • 如何通过散点图发现异常值?

  • 当数据点过多重叠时,如何改进可视化效果?

  • 如何添加颜色维度表示第三个变量?

综合练习¶

根据iris_np.csv数据,完成下面的任务

题目1:折线图​​¶

​​要求​​:绘制不同鸢尾花物种(setosa, versicolor, virginica)的萼片长度(Sepal.Length)随样本索引变化的折线图,用不同颜色区分物种,并添加图例和坐标轴标签。

In [6]:
import matplotlib.pyplot as plt
import pandas as pd

# 假设数据已加载为DataFrame,列名正确
df = pd.read_csv('C:/Users/Zhouq/Desktop/iris_np.csv')

plt.figure(figsize=(10, 6))
for species in df['Species'].unique():
    species_data = df[df['Species'] == species]
    plt.plot(species_data.index, species_data['Sepal.Length'], label=species)

plt.xlabel('Sample Index')
plt.ylabel('Sepal Length (cm)')
plt.title('Sepal Length Variation by Species')
plt.legend()
plt.show()
C:\Users\Zhouq\AppData\Roaming\Python\Python39\site-packages\pandas\core\computation\expressions.py:21: UserWarning: Pandas requires version '2.8.4' or newer of 'numexpr' (version '2.8.3' currently installed).
  from pandas.core.computation.check import NUMEXPR_INSTALLED
C:\Users\Zhouq\AppData\Roaming\Python\Python39\site-packages\pandas\core\arrays\masked.py:60: UserWarning: Pandas requires version '1.3.6' or newer of 'bottleneck' (version '1.3.5' currently installed).
  from pandas.core import (

题目2:柱状图​​¶

​​要求​​:比较三个物种在四个特征(萼片长度、萼片宽度、花瓣长度、花瓣宽度)上的平均值,绘制四个子图,每个子图显示一个特征的物种对比柱状图。

In [7]:
import matplotlib.pyplot as plt
import pandas as pd

df = pd.read_csv('iris_np.csv')
means = df.groupby('Species').mean()  # 计算各物种均值

features = ['Sepal.Length', 'Sepal.Width', 'Petal.Length', 'Petal.Width']
plt.figure(figsize=(12, 8))
for i, feature in enumerate(features, 1):
    plt.subplot(2, 2, i)
    plt.bar(means.index, means[feature], color=['blue', 'green', 'red'])
    plt.title(f'Average {feature}')
    plt.ylabel('cm')

plt.tight_layout()
plt.show()

题目3:散点图​​¶

​​要求​​:绘制萼片长度(Sepal.Length)与花瓣长度(Petal.Length)的散点图,点颜色表示不同物种,添加图例、标题和轴标签。

In [8]:
import matplotlib.pyplot as plt
import pandas as pd

df = pd.read_csv('iris_np.csv')
colors = {'setosa': 'blue', 'versicolor': 'green', 'virginica': 'red'}

plt.figure(figsize=(10, 6))
for species, color in colors.items():
    species_data = df[df['Species'] == species]
    plt.scatter(species_data['Sepal.Length'], species_data['Petal.Length'],
                color=color, label=species, alpha=0.7)

plt.xlabel('Sepal Length (cm)')
plt.ylabel('Petal Length (cm)')
plt.title('Sepal vs Petal Length by Species')
plt.legend()
plt.show()

5. 综合应用与作业¶

请参考上述示例,完成相应图表作业,注意根据数据特性选择合适的图表类型,并合理美化图表。

5.1 图表选择指南¶

图表类型 适用场景 人文社科示例
折线图 趋势分析 人口变化、经济指标
柱状图 比较分类 不同地区文化设施数量
散点图 关系分析 教育投入与成果关系

5.2 作业详细要求¶

折线图作业¶

  1. 数据要求:
    • 收集真实数据(推荐国家统计局网站)
    • 时间跨度≥5个时间点
    • 数据需包含完整时间序列

5.3 常见问题解答¶

Q1:如何保存高清图表?

In [ ]:
plt.savefig('output.png', 
           dpi=300,                   # 分辨率
           bbox_inches='tight',       # 去除白边
           transparent=True)          # 透明背景(可选)

Q2:中文显示异常怎么办?

In [ ]:
# 解决方案一:指定中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows
# plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']  # Mac

# 解决方案二:使用具体字体路径
# import matplotlib.font_manager as fm
# font_path = 'your_chinese_font.ttf'#替换自己的字体
# font_prop = fm.FontProperties(fname=font_path)
# plt.title("标题", fontproperties=font_prop)

Q3:如何调整图例样式?

In [ ]:
plt.legend(
    loc='upper left',          # 位置设置
    frameon=False,            # 去除边框
    ncol=2,                   # 分列显示
    prop={'size': 10}         # 字体大小
)

Q4:图表元素太多太拥挤?

In [ ]:
plt.tight_layout()  # 自动调整布局
# 或手动调整
plt.subplots_adjust(
    left=0.1, 
    right=0.9, 
    top=0.9, 
    bottom=0.2
)