Python轮子:matpotlib-3d散点图

原文链接: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三维散点图的多种绘制技巧,涵盖基础绘图、颜色映射、多类别展示和交互式可视化等方法。这些技术可应用于科学数据分析、机器学习可视化等多个领域,帮助用户直观理解三维数据的分布特征和内在规律。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注