原文链接:http://www.juzicode.com/python-module-matplotlib-3d-plotting-scatter
本文将详细介绍Matplotlib三维散点图的绘制方法,展示多种数据可视化技巧。
应用场景
- 多变量数据分析
- 聚类分析与模式识别
- 科学实验数据可视化
- 地理空间坐标展示
- 机器学习特征分布
安装与导入
import matplotlib.pyplot as plt
import numpy as np
三维散点图绘制方法
1)基础3D散点图
创建随机分布的三维散点图,展示基本绘图方法:
# juzicode.com/VX公众号:juzicode
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.family'] = 'YouYuan'
plt.rcParams['axes.unicode_minus'] = False
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
# 生成随机数据
np.random.seed(42)
n_points = 300
x = np.random.randn(n_points)
y = np.random.randn(n_points)
z = np.random.randn(n_points)
# 绘制散点图
ax.scatter(x, y, z, c='blue', marker='o', alpha=0.7)
ax.set_title('基础3D散点图', fontsize=14)
ax.set_xlabel('X轴', fontsize=12)
ax.set_ylabel('Y轴', fontsize=12)
ax.set_zlabel('Z轴', fontsize=12)
plt.tight_layout()
plt.show()

2)颜色映射散点图
根据Z轴数值进行颜色映射,使用彩虹色系展示数据分布:
# juzicode.com/VX公众号:juzicode
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
plt.rcParams['font.family'] = 'YouYuan'
plt.rcParams['axes.unicode_minus'] = False
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
# 生成螺旋状数据
n_points = 500
theta = np.linspace(0, 8*np.pi, n_points)
z = np.linspace(0, 10, n_points)
x = np.sin(theta) * z
y = np.cos(theta) * z
# 根据Z值进行颜色映射
scatter = ax.scatter(x, y, z, c=z, cmap=cm.rainbow,
marker='o', alpha=0.8, s=20)
ax.set_title('螺旋状数据颜色映射', fontsize=14)
ax.set_xlabel('X轴', fontsize=12)
ax.set_ylabel('Y轴', fontsize=12)
ax.set_zlabel('Z轴', fontsize=12)
# 添加颜色条
cbar = fig.colorbar(scatter, ax=ax, pad=0.1)
cbar.set_label('Z值', fontsize=12)
plt.tight_layout()
plt.show()

3)多类别散点图
展示不同类别的数据点,使用不同颜色和标记区分:
# juzicode.com/VX公众号:juzicode
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.family'] = 'YouYuan'
plt.rcParams['axes.unicode_minus'] = False
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection='3d')
# 生成三类数据
np.random.seed(42)
n_per_class = 100
# 类别1: 球形分布
x1 = np.random.randn(n_per_class)
y1 = np.random.randn(n_per_class)
z1 = np.random.randn(n_per_class)
# 类别2: 平面分布
x2 = 3 + np.random.rand(n_per_class) * 2
y2 = 3 + np.random.rand(n_per_class) * 2
z2 = np.zeros(n_per_class)
# 类别3: 线性分布
x3 = np.linspace(-4, 4, n_per_class)
y3 = np.linspace(-4, 4, n_per_class)
z3 = x3 + y3 + np.random.randn(n_per_class)*0.5
# 绘制不同类别的散点
ax.scatter(x1, y1, z1, c='red', marker='o', s=30, alpha=0.7, label='球形分布')
ax.scatter(x2, y2, z2, c='green', marker='^', s=40, alpha=0.7, label='平面分布')
ax.scatter(x3, y3, z3, c='blue', marker='s', s=20, alpha=0.7, label='线性分布')
ax.set_title('多类别3D散点图', fontsize=14)
ax.set_xlabel('X轴', fontsize=12)
ax.set_ylabel('Y轴', fontsize=12)
ax.set_zlabel('Z轴', fontsize=12)
ax.legend(loc='upper left', fontsize=10)
# 调整视角
ax.view_init(elev=25, azim=-45)
plt.tight_layout()
plt.show()

4)动态旋转散点图
创建可交互的3D散点图,支持动态旋转查看:
# juzicode.com/VX公众号:juzicode
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
plt.rcParams['font.family'] = 'YouYuan'
plt.rcParams['axes.unicode_minus'] = False
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection='3d')
# 生成高斯分布数据
np.random.seed(42)
n_points = 1000
# 三个高斯分布簇
means = [[0, 0, 0], [3, 3, 3], [-2, 4, -1]]
covs = [np.eye(3), np.diag([0.5, 2, 1]), np.array([[1,0.5,0],[0.5,1,0],[0,0,2]])]
all_points = []
for i in range(3):
points = np.random.multivariate_normal(means[i], covs[i], n_points//3)
all_points.append(points)
all_points = np.vstack(all_points)
x, y, z = all_points[:,0], all_points[:,1], all_points[:,2]
# 根据位置计算颜色
colors = np.arctan2(y, x)
scatter = ax.scatter(x, y, z, c=colors, cmap='viridis',
marker='o', s=20, alpha=0.7)
ax.set_title('可旋转的3D散点图', fontsize=14)
ax.set_xlabel('X轴', fontsize=12)
ax.set_ylabel('Y轴', fontsize=12)
ax.set_zlabel('Z轴', fontsize=12)
# 添加颜色条
cbar = fig.colorbar(scatter, ax=ax, pad=0.1)
cbar.set_label('角度值', fontsize=12)
# 设置初始视角
ax.view_init(elev=30, azim=45)
plt.tight_layout()
plt.show()

5)时间序列动态散点图
展示随时间变化的三维数据演化过程,使用颜色和大小表示时间维度:
# juzicode.com/VX公众号:juzicode
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation
from matplotlib import cm
plt.rcParams['font.family'] = 'YouYuan'
plt.rcParams['axes.unicode_minus'] = False
# 创建图形和3D坐标轴
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
# 生成时间序列数据
n_frames = 50
n_points = 200
t = np.linspace(0, 4*np.pi, n_frames)
# 初始化空散点图
scatter = ax.scatter([], [], [], s=20, alpha=0.8)
# 设置坐标轴范围
ax.set_xlim(-10, 10)
ax.set_ylim(-10, 10)
ax.set_zlim(-2, 2)
ax.set_title('三维动态散点图', fontsize=14)
ax.set_xlabel('X轴', fontsize=12)
ax.set_ylabel('Y轴', fontsize=12)
ax.set_zlabel('Z轴', fontsize=12)
# 更新函数
def update(frame):
# 清除当前散点
ax.cla()
# 设置坐标轴范围
ax.set_xlim(-10, 10)
ax.set_ylim(-10, 10)
ax.set_zlim(-2, 2)
ax.set_title(f'时间步: {frame+1}/{n_frames}', fontsize=14)
ax.set_xlabel('X轴', fontsize=12)
ax.set_ylabel('Y轴', fontsize=12)
ax.set_zlabel('Z轴', fontsize=12)
# 计算新位置
theta = np.linspace(0, 2*np.pi, n_points)
r = np.linspace(0, 8, n_points)
x = r * np.cos(theta + t[frame])
y = r * np.sin(theta + t[frame])
z = np.sin(2*theta + t[frame])
# 根据时间变化设置颜色和大小
sizes = 30 + 70 * np.sin(0.1*frame)**2
colors = np.arctan2(y, x)
# 绘制新散点
scatter = ax.scatter(x, y, z, c=colors, cmap='hsv',
s=sizes, alpha=0.7, edgecolors='w')
return scatter,
# 创建动画
ani = FuncAnimation(fig, update, frames=n_frames, interval=100, blit=False)
plt.tight_layout()
plt.show()
# 保存动画(可选)
# ani.save('3d_scatter_animation.gif', writer='pillow', fps=10)

本文详细介绍了Matplotlib三维散点图的多种绘制技巧,涵盖基础绘图、颜色映射、多类别展示和交互式可视化等方法。这些技术可应用于科学数据分析、机器学习可视化等多个领域,帮助用户直观理解三维数据的分布特征和内在规律。