Matplotlib 散点图(详细教程)

Matplotlib 散点图:用点来发现数据之间的秘密

在数据分析的世界里,有些信息无法通过表格一眼看透。比如,你有一组学生的身高和体重数据,单纯看数字你可能看不出规律。但如果你把这些数据画成一个个小点,它们的位置关系就会悄悄告诉你:高个子的学生是不是普遍更重?这就是 Matplotlib 散点图的魅力所在。

散点图(Scatter Plot)是可视化数据关系的利器,特别适合观察两个变量之间的相关性。它用点的位置表示两个维度的数值,点的分布形态能揭示出隐藏在数据背后的模式。无论是科研、商业分析还是个人项目,掌握 Matplotlib 散点图都是提升数据表达力的重要一步。

今天,我们就从零开始,一步步教你如何用 Python 的 Matplotlib 库绘制出专业级的散点图。不讲空话,只讲实操,哪怕你是编程新手,也能跟上节奏。


安装与导入基础库

在动手之前,你需要确保系统中已经安装了 Matplotlib 和 NumPy。它们是绘图的“双子星”:NumPy 负责处理数值计算,Matplotlib 负责把数据变成图像。

打开终端(或命令行),运行以下命令安装:

pip install matplotlib numpy

安装完成后,我们在 Python 脚本或 Jupyter Notebook 中导入这两个库:

import matplotlib.pyplot as plt
import numpy as np

这里 plt 是 Matplotlib 的常用别名,np 是 NumPy 的别名。这样写更简洁,也符合 Python 社区的惯例。


创建数组与初始化数据

要画散点图,首先得有数据。我们先模拟一组学生的身高(单位:厘米)和体重(单位:公斤)数据。这就像在准备一份“学生档案”。

np.random.seed(42)

heights = np.random.normal(170, 10, 50)

weights = 50 + 0.5 * heights + np.random.normal(0, 5, 50)

print("前 5 名学生的身高和体重:")
for i in range(5):
    print(f"学生 {i+1}: 身高 {heights[i]:.1f}cm, 体重 {weights[i]:.1f}kg")

这段代码的关键点是:

  • np.random.normal(170, 10, 50):生成 50 个符合正态分布的身高值,均值 170,标准差 10,模拟真实人群。
  • weights = 50 + 0.5 * heights + np.random.normal(0, 5, 50):建立身高与体重的线性关系,同时加入随机噪声,更贴近现实。
  • print 输出前几条数据,帮助你理解数据结构。

现在,heightsweights 就是我们的散点图“原料”。


绘制基础散点图

有了数据,接下来就是画图。Matplotlib 提供了 scatter() 函数专门用于绘制散点图。

plt.figure(figsize=(8, 6))

plt.scatter(heights, weights, color='blue', alpha=0.7)

plt.title('学生身高与体重关系散点图')
plt.xlabel('身高 (cm)')
plt.ylabel('体重 (kg)')

plt.show()

解释一下关键参数:

  • plt.figure(figsize=(8, 6)):设置图像的尺寸,避免太小或太大。
  • plt.scatter(heights, weights):第一个参数是 x 值(身高),第二个是 y 值(体重)。
  • color='blue':设置点的颜色,蓝色是最常见的选择。
  • alpha=0.7:控制透明度,0.7 表示半透明,避免点重叠时看不清。
  • plt.xlabelplt.ylabel:给坐标轴加标签,让图表更清晰。
  • plt.show():真正显示图像。

运行这段代码,你会看到一个蓝色的点阵,大致呈从左下到右上的趋势——这正是身高与体重正相关的直观体现。


优化散点图:颜色与大小的魔法

一个好图表不仅要“能看”,还要“好看”。我们可以让散点图更生动:比如用颜色表示不同班级,用大小表示成绩。

假设我们给学生加上“班级”信息(A班或B班),并用不同颜色区分。

classes = np.random.choice(['A班', 'B班'], size=50)

colors = ['red' if c == 'A班' else 'green' for c in classes]

plt.figure(figsize=(8, 6))
plt.scatter(heights, weights, c=colors, alpha=0.7, s=60)

plt.title('不同班级学生身高与体重关系')
plt.xlabel('身高 (cm)')
plt.ylabel('体重 (kg)')

from matplotlib.patches import Patch
legend_elements = [
    Patch(facecolor='red', label='A班'),
    Patch(facecolor='green', label='B班')
]
plt.legend(handles=legend_elements)

plt.show()

这里的关键是:

  • c=colors:让每个点的颜色由 colors 列表决定。
  • s=60:设置点的大小,数值越大点越大。
  • Patchlegend:用来添加图例,让读者知道颜色代表什么。

这就像给散点图“贴标签”,让信息一目了然。


添加趋势线:从点到规律

散点图的真正价值,往往在于发现趋势。我们可以通过拟合一条直线来描述两个变量的关系。

使用 NumPy 的 polyfit 函数,可以快速计算最佳拟合线。

k, b = np.polyfit(heights, weights, 1)

x_line = np.linspace(heights.min(), heights.max(), 100)
y_line = k * x_line + b

plt.figure(figsize=(8, 6))
plt.scatter(heights, weights, c='blue', alpha=0.7, s=60)

plt.plot(x_line, y_line, color='red', linewidth=2, label=f'趋势线: y={k:.2f}x+{b:.2f}')

plt.title('身高与体重关系及趋势线')
plt.xlabel('身高 (cm)')
plt.ylabel('体重 (kg)')
plt.legend()

plt.show()

说明:

  • np.polyfit(heights, weights, 1):拟合一次多项式(即直线),返回斜率和截距。
  • x_line:生成一条横跨数据范围的平滑线。
  • plt.plot():在散点图上叠加一条线。
  • label:为趋势线添加说明,图例会自动显示。

这条红线就是“平均规律”——它告诉我们,每增加 1cm 身高,体重平均增加约 0.5kg。


高级技巧:多子图与自定义样式

当你要对比多个数据集时,可以把多个散点图放在同一个窗口里,这就是“子图”(Subplot)。

fig, axes = plt.subplots(2, 2, figsize=(12, 10))

axes[0, 0].scatter(heights, weights, color='blue', alpha=0.7)
axes[0, 0].set_title('原始数据')
axes[0, 0].set_xlabel('身高 (cm)')
axes[0, 0].set_ylabel('体重 (kg)')

axes[0, 1].scatter(heights, weights, c=colors, alpha=0.7, s=60)
axes[0, 1].set_title('按班级着色')
axes[0, 1].set_xlabel('身高 (cm)')
axes[0, 1].set_ylabel('体重 (kg)')

axes[1, 0].scatter(heights, weights, color='purple', alpha=0.7)
axes[1, 0].plot(x_line, y_line, color='red', linewidth=2)
axes[1, 0].set_title('带趋势线')
axes[1, 0].set_xlabel('身高 (cm)')
axes[1, 0].set_ylabel('体重 (kg)')

scores = np.random.normal(75, 10, 50)  # 模拟成绩
axes[1, 1].scatter(heights, weights, s=scores*1.5, alpha=0.6, c='orange')
axes[1, 1].set_title('点大小表示成绩')
axes[1, 1].set_xlabel('身高 (cm)')
axes[1, 1].set_ylabel('体重 (kg)')

plt.tight_layout()

plt.show()

这个例子展示了:

  • plt.subplots(2, 2):创建 2 行 2 列的子图。
  • axes[i, j]:访问每个子图的坐标。
  • plt.tight_layout():自动调整子图间距,防止标签被遮挡。

总结与建议

Matplotlib 散点图是数据分析中最基础也最实用的工具之一。它不仅能展示数据分布,还能帮助我们发现变量之间的潜在联系。

从基础的点图,到带颜色、大小、趋势线的进阶图表,每一步都在提升你的表达能力。记住:

  • 数据是根,图表是叶。
  • 一个好图表,能胜过千言万语。
  • 不要只画图,更要思考“这个图在说什么”。

掌握 Matplotlib 散点图,不仅是学会一个函数,更是培养一种“用图形理解世界”的思维方式。无论你是学生、工程师,还是数据爱好者,这都是一份值得收藏的技能。

现在,就打开你的 Python 环境,把这段代码跑一遍,看看那些沉默的数据,如何在你的笔下“说话”。