散点图用于展示两个变量之间的关系,每个点代表一个观测值。在 Matplotlib 中,
使用 plt.scatter() 函数可以轻松绘制散点图,并且可以通过颜色、大小和形状映射更多维度的信息。
最简单的散点图只需要提供 x 和 y 坐标:
import matplotlib.pyplot as plt
import numpy as np
# 生成随机数据
x = np.random.randn(100)
y = np.random.randn(100)
plt.scatter(x, y)
plt.title('基础散点图')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
scatter() 提供丰富的参数来控制点的外观:
| 参数 | 说明 | 常用值示例 |
|---|---|---|
s | 点的大小(数值或数组,单位为像素的平方) | s=50(统一大小),s=np.random.rand(100)*100 |
c | 点的颜色(单一颜色或颜色序列) | c='red', c=['r','g','b'], c=np.random.rand(100)(配合cmap) |
marker | 点的形状 | 'o'(圆圈)、's'(正方形)、'^'(三角形)、'*'(星号)等 |
alpha | 透明度(0~1) | alpha=0.5 |
linewidths | 点边缘线宽 | linewidths=1 |
edgecolors | 点边缘颜色 | edgecolors='black' |
x = np.random.randn(50)
y = np.random.randn(50)
colors = np.random.rand(50)
sizes = (np.random.rand(50) * 100) + 20
plt.scatter(x, y, c=colors, s=sizes, alpha=0.6, marker='^',
edgecolors='black', linewidths=0.5)
plt.colorbar() # 显示颜色条(需要c为数值序列)
plt.title('定制样式的散点图')
plt.show()
当 c 参数传入数值序列时,可以配合 cmap 参数使用颜色映射,将数值映射到颜色上,适合展示第三个维度的信息。
# 生成数据
x = np.random.randn(200)
y = np.random.randn(200)
z = x**2 + y**2 # 第三个维度(到原点的距离平方)
plt.scatter(x, y, c=z, s=50, cmap='viridis', alpha=0.7)
plt.colorbar(label='距离平方') # 显示颜色条并添加标签
plt.title('颜色映射示例 (viridis)')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
cmap 指定颜色映射方案,如 'plasma', 'inferno', 'coolwarm' 等。对于分类数据,可以分别绘制不同类别的点并添加图例:
# 生成三个类别的数据
np.random.seed(42)
x1, y1 = np.random.randn(2, 30) + [0, 0] # 类别A
x2, y2 = np.random.randn(2, 30) + [2, 2] # 类别B
x3, y3 = np.random.randn(2, 30) + [-1, 2] # 类别C
plt.scatter(x1, y1, c='red', label='类别 A', alpha=0.6, edgecolors='w')
plt.scatter(x2, y2, c='blue', label='类别 B', alpha=0.6, edgecolors='w')
plt.scatter(x3, y3, c='green', label='类别 C', alpha=0.6, edgecolors='w')
plt.legend()
plt.title('分组散点图')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
scatter 并指定 label 实现分组。将 s 参数设为数据序列,可以绘制气泡图,点的大小反映另一个变量的大小:
# 假设有四个维度:x, y, 人口, 面积
cities = ['北京', '上海', '广州', '深圳']
x = [116.4, 121.5, 113.3, 114.1] # 经度
y = [39.9, 31.2, 23.1, 22.5] # 纬度
population = [21.54, 24.28, 15.30, 17.56] # 人口(百万人)
area = [16410, 6340, 7434, 1997] # 面积(km²)
plt.scatter(x, y, s=population, c=area, cmap='Reds', alpha=0.7, edgecolors='black')
plt.colorbar(label='面积 (km²)')
# 添加城市标签
for i, city in enumerate(cities):
plt.annotate(city, (x[i], y[i]), fontsize=12)
plt.title('中国主要城市:气泡大小=人口,颜色=面积')
plt.xlabel('经度')
plt.ylabel('纬度')
plt.show()
可以在同一图表中组合 plot 和 scatter,例如绘制数据点及其拟合线:
x = np.linspace(0, 10, 20)
y = 2 * x + 1 + np.random.randn(20) * 2 # 带噪声的线性数据
# 散点:原始数据
plt.scatter(x, y, color='blue', label='观测值')
# 折线:理论线
x_line = np.linspace(0, 10, 100)
y_line = 2 * x_line + 1
plt.plot(x_line, y_line, 'r--', label='理论线 y=2x+1')
plt.legend()
plt.title('散点图与折线图结合')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
使用 subplots 创建多个子图,展示不同样式的散点图:
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
x = np.random.randn(100)
y = np.random.randn(100)
# 左上:默认样式
axes[0, 0].scatter(x, y)
axes[0, 0].set_title('默认样式')
# 右上:不同标记和透明度
axes[0, 1].scatter(x, y, c='red', marker='s', alpha=0.3)
axes[0, 1].set_title('红色方块')
# 左下:颜色映射
axes[1, 0].scatter(x, y, c=x+y, cmap='coolwarm', s=50)
axes[1, 0].set_title('颜色映射 (x+y)')
# 右下:大小变化
sizes = (x - y)**2 * 50
axes[1, 1].scatter(x, y, s=sizes, alpha=0.5, c='green')
axes[1, 1].set_title('大小变化')
plt.tight_layout()
plt.show()
和折线图一样,使用 savefig() 保存散点图:
plt.scatter(x, y)
plt.title('散点图保存示例')
plt.savefig('scatter_plot.png', dpi=300, bbox_inches='tight')
散点图是探索变量关系的有力工具,配合颜色映射和大小映射可以呈现多维数据。下一章将介绍柱状图的绘制方法。