4.1 热力图与等高线图
4.1.1 热力图(Heatmap)
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
import seaborn as sns
from scipy import ndimage
class HeatmapDemo:
"""热力图演示类"""
def __init__(self):
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
# 生成示例数据
np.random.seed(42)
self.correlation_data = np.random.randn(10, 10)
self.correlation_matrix = np.corrcoef(self.correlation_data)
# 时间序列热力图数据
self.time_data = np.random.randn(24, 7) # 24小时 x 7天
self.hours = [f'{i:02d}:00' for i in range(24)]
self.days = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
def basic_heatmap(self):
"""基本热力图"""
fig, axes = plt.subplots(2, 2, figsize=(16, 12))
# 1. 基本热力图
im1 = axes[0, 0].imshow(self.correlation_matrix, cmap='coolwarm',
vmin=-1, vmax=1)
axes[0, 0].set_title('基本相关性热力图')
plt.colorbar(im1, ax=axes[0, 0])
# 2. 带标签的热力图
im2 = axes[0, 1].imshow(self.correlation_matrix, cmap='RdYlBu_r',
vmin=-1, vmax=1)
# 添加数值标签
for i in range(self.correlation_matrix.shape[0]):
for j in range(self.correlation_matrix.shape[1]):
text = axes[0, 1].text(j, i, f'{self.correlation_matrix[i, j]:.2f}',
ha='center', va='center',
color='white' if abs(self.correlation_matrix[i, j]) > 0.5 else 'black')
axes[0, 1].set_title('带数值标签的热力图')
plt.colorbar(im2, ax=axes[0, 1])
# 3. 时间序列热力图
im3 = axes[1, 0].imshow(self.time_data, cmap='viridis', aspect='auto')
axes[1, 0].set_xticks(range(len(self.days)))
axes[1, 0].set_xticklabels(self.days)
axes[1, 0].set_yticks(range(0, 24, 4))
axes[1, 0].set_yticklabels([f'{i:02d}:00' for i in range(0, 24, 4)])
axes[1, 0].set_title('时间序列热力图')
axes[1, 0].set_xlabel('星期')
axes[1, 0].set_ylabel('小时')
plt.colorbar(im3, ax=axes[1, 0])
# 4. 自定义颜色映射热力图
colors = ['#000080', '#0000FF', '#00FFFF', '#FFFF00', '#FF0000']
custom_cmap = LinearSegmentedColormap.from_list('custom', colors)
im4 = axes[1, 1].imshow(self.time_data, cmap=custom_cmap, aspect='auto')
axes[1, 1].set_title('自定义颜色映射热力图')
plt.colorbar(im4, ax=axes[1, 1])
plt.tight_layout()
plt.show()
def advanced_heatmap(self):
"""高级热力图功能"""
fig, axes = plt.subplots(2, 2, figsize=(16, 12))
# 1. 分层热力图
# 创建分层数据
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, y)
Z = np.exp(-(X**2 + Y**2)/2)
levels = np.linspace(0, 1, 11)
cs = axes[0, 0].contourf(X, Y, Z, levels=levels, cmap='plasma')
axes[0, 0].set_title('分层热力图')
plt.colorbar(cs, ax=axes[0, 0])
# 2. 掩码热力图
# 创建掩码(隐藏部分数据)
mask = np.triu(np.ones_like(self.correlation_matrix, dtype=bool))
masked_data = np.ma.masked_where(mask, self.correlation_matrix)
im2 = axes[0, 1].imshow(masked_data, cmap='coolwarm', vmin=-1, vmax=1)
axes[0, 1].set_title('掩码热力图(下三角)')
plt.colorbar(im2, ax=axes[0, 1])
# 3. 插值热力图
# 稀疏数据点
sparse_x = np.random.uniform(-3, 3, 20)
sparse_y = np.random.uniform(-3, 3, 20)
sparse_z = np.sin(sparse_x) * np.cos(sparse_y)
# 创建网格进行插值
xi = np.linspace(-3, 3, 50)
yi = np.linspace(-3, 3, 50)
Xi, Yi = np.meshgrid(xi, yi)
# 使用scipy进行插值
from scipy.interpolate import griddata
Zi = griddata((sparse_x, sparse_y), sparse_z, (Xi, Yi), method='cubic')
im3 = axes[1, 0].imshow(Zi, extent=[-3, 3, -3, 3], origin='lower',
cmap='RdYlBu_r')
axes[1, 0].scatter(sparse_x, sparse_y, c='black', s=30, alpha=0.7)
axes[1, 0].set_title('插值热力图')
axes[1, 0].set_xlabel('X')
axes[1, 0].set_ylabel('Y')
plt.colorbar(im3, ax=axes[1, 0])
# 4. 多层叠加热力图
# 创建两个不同的数据层
layer1 = np.random.randn(20, 20)
layer2 = np.random.randn(20, 20)
# 第一层
im4a = axes[1, 1].imshow(layer1, cmap='Reds', alpha=0.7)
# 第二层(叠加)
im4b = axes[1, 1].imshow(layer2, cmap='Blues', alpha=0.5)
axes[1, 1].set_title('多层叠加热力图')
# 创建自定义图例
from matplotlib.patches import Patch
legend_elements = [Patch(facecolor='red', alpha=0.7, label='层1'),
Patch(facecolor='blue', alpha=0.5, label='层2')]
axes[1, 1].legend(handles=legend_elements, loc='upper right')
plt.tight_layout()
plt.show()
def interactive_heatmap(self):
"""交互式热力图"""
fig, ax = plt.subplots(figsize=(12, 10))
# 创建热力图
im = ax.imshow(self.correlation_matrix, cmap='coolwarm', vmin=-1, vmax=1)
# 添加颜色条
cbar = plt.colorbar(im, ax=ax)
cbar.set_label('相关系数', rotation=270, labelpad=20)
# 添加数值标签
for i in range(self.correlation_matrix.shape[0]):
for j in range(self.correlation_matrix.shape[1]):
text = ax.text(j, i, f'{self.correlation_matrix[i, j]:.2f}',
ha='center', va='center', fontsize=10,
color='white' if abs(self.correlation_matrix[i, j]) > 0.5 else 'black')
# 设置标签
variables = [f'变量{i+1}' for i in range(self.correlation_matrix.shape[0])]
ax.set_xticks(range(len(variables)))
ax.set_yticks(range(len(variables)))
ax.set_xticklabels(variables, rotation=45, ha='right')
ax.set_yticklabels(variables)
ax.set_title('交互式相关性热力图', fontsize=16, fontweight='bold')
# 添加网格
ax.set_xticks(np.arange(-.5, len(variables), 1), minor=True)
ax.set_yticks(np.arange(-.5, len(variables), 1), minor=True)
ax.grid(which='minor', color='white', linestyle='-', linewidth=2)
plt.tight_layout()
plt.show()
# 使用示例
heatmap_demo = HeatmapDemo()
heatmap_demo.basic_heatmap()
heatmap_demo.advanced_heatmap()
heatmap_demo.interactive_heatmap()
4.1.2 等高线图(Contour Plot)
class ContourDemo:
"""等高线图演示类"""
def __init__(self):
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
# 生成示例数据
self.x = np.linspace(-3, 3, 100)
self.y = np.linspace(-3, 3, 100)
self.X, self.Y = np.meshgrid(self.x, self.y)
self.Z1 = np.exp(-(self.X**2 + self.Y**2)/2)
self.Z2 = np.sin(self.X) * np.cos(self.Y)
def basic_contour(self):
"""基本等高线图"""
fig, axes = plt.subplots(2, 2, figsize=(16, 12))
# 1. 基本等高线
cs1 = axes[0, 0].contour(self.X, self.Y, self.Z1)
axes[0, 0].clabel(cs1, inline=True, fontsize=10)
axes[0, 0].set_title('基本等高线图')
axes[0, 0].set_xlabel('X')
axes[0, 0].set_ylabel('Y')
# 2. 填充等高线
cs2 = axes[0, 1].contourf(self.X, self.Y, self.Z1, levels=20, cmap='viridis')
axes[0, 1].set_title('填充等高线图')
axes[0, 1].set_xlabel('X')
axes[0, 1].set_ylabel('Y')
plt.colorbar(cs2, ax=axes[0, 1])
# 3. 自定义等高线级别
levels = [-0.5, -0.25, 0, 0.25, 0.5, 0.75, 1.0]
cs3 = axes[1, 0].contour(self.X, self.Y, self.Z2, levels=levels,
colors=['red', 'orange', 'yellow', 'green',
'blue', 'purple', 'black'])
axes[1, 0].clabel(cs3, inline=True, fontsize=10)
axes[1, 0].set_title('自定义等高线级别')
axes[1, 0].set_xlabel('X')
axes[1, 0].set_ylabel('Y')
# 4. 组合等高线
cs4_filled = axes[1, 1].contourf(self.X, self.Y, self.Z1, levels=15,
cmap='RdYlBu_r', alpha=0.7)
cs4_lines = axes[1, 1].contour(self.X, self.Y, self.Z1, levels=15,
colors='black', linewidths=0.5)
axes[1, 1].clabel(cs4_lines, inline=True, fontsize=8)
axes[1, 1].set_title('组合等高线图')
axes[1, 1].set_xlabel('X')
axes[1, 1].set_ylabel('Y')
plt.colorbar(cs4_filled, ax=axes[1, 1])
plt.tight_layout()
plt.show()
def advanced_contour(self):
"""高级等高线图"""
fig, axes = plt.subplots(2, 2, figsize=(16, 12))
# 1. 3D效果等高线
from mpl_toolkits.mplot3d import Axes3D
ax1 = plt.subplot(2, 2, 1, projection='3d')
surf = ax1.plot_surface(self.X, self.Y, self.Z1, cmap='viridis', alpha=0.8)
contours = ax1.contour(self.X, self.Y, self.Z1, zdir='z', offset=-0.1,
cmap='viridis')
ax1.set_title('3D表面与等高线')
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
ax1.set_zlabel('Z')
# 2. 梯度场等高线
# 计算梯度
dy, dx = np.gradient(self.Z2)
cs2 = axes[0, 1].contour(self.X, self.Y, self.Z2, levels=10, colors='blue')
axes[0, 1].quiver(self.X[::5, ::5], self.Y[::5, ::5],
dx[::5, ::5], dy[::5, ::5],
alpha=0.7, scale=20, color='red')
axes[0, 1].set_title('等高线与梯度场')
axes[0, 1].set_xlabel('X')
axes[0, 1].set_ylabel('Y')
# 3. 多函数等高线对比
cs3a = axes[1, 0].contour(self.X, self.Y, self.Z1, levels=8,
colors='blue', linestyles='solid', linewidths=2)
cs3b = axes[1, 0].contour(self.X, self.Y, self.Z2, levels=8,
colors='red', linestyles='dashed', linewidths=2)
axes[1, 0].clabel(cs3a, inline=True, fontsize=8, fmt='Z1: %.2f')
axes[1, 0].clabel(cs3b, inline=True, fontsize=8, fmt='Z2: %.2f')
axes[1, 0].set_title('多函数等高线对比')
axes[1, 0].set_xlabel('X')
axes[1, 0].set_ylabel('Y')
# 添加图例
from matplotlib.lines import Line2D
legend_elements = [Line2D([0], [0], color='blue', lw=2, label='函数1'),
Line2D([0], [0], color='red', lw=2, linestyle='--', label='函数2')]
axes[1, 0].legend(handles=legend_elements)
# 4. 极坐标等高线
ax4 = plt.subplot(2, 2, 4, projection='polar')
# 创建极坐标数据
r = np.linspace(0, 3, 50)
theta = np.linspace(0, 2*np.pi, 100)
R, THETA = np.meshgrid(r, theta)
Z_polar = R * np.sin(3*THETA)
cs4 = ax4.contourf(THETA, R, Z_polar, levels=20, cmap='plasma')
ax4.set_title('极坐标等高线图')
plt.colorbar(cs4, ax=ax4, shrink=0.8)
plt.tight_layout()
plt.show()
def contour_applications(self):
"""等高线图应用示例"""
fig, axes = plt.subplots(2, 2, figsize=(16, 12))
# 1. 地形图模拟
# 创建地形数据
x_terrain = np.linspace(0, 10, 100)
y_terrain = np.linspace(0, 10, 100)
X_terrain, Y_terrain = np.meshgrid(x_terrain, y_terrain)
# 模拟山峰和山谷
Z_terrain = (np.sin(X_terrain/2) * np.cos(Y_terrain/2) *
np.exp(-((X_terrain-5)**2 + (Y_terrain-5)**2)/10))
cs1 = axes[0, 0].contourf(X_terrain, Y_terrain, Z_terrain,
levels=20, cmap='terrain')
contour_lines = axes[0, 0].contour(X_terrain, Y_terrain, Z_terrain,
levels=10, colors='black', linewidths=0.5)
axes[0, 0].clabel(contour_lines, inline=True, fontsize=8)
axes[0, 0].set_title('地形等高线图')
axes[0, 0].set_xlabel('经度')
axes[0, 0].set_ylabel('纬度')
plt.colorbar(cs1, ax=axes[0, 0], label='海拔(m)')
# 2. 温度分布图
# 创建温度数据
x_temp = np.linspace(-5, 5, 80)
y_temp = np.linspace(-5, 5, 80)
X_temp, Y_temp = np.meshgrid(x_temp, y_temp)
# 模拟热源
Z_temp = (30 * np.exp(-((X_temp+2)**2 + (Y_temp+1)**2)/2) +
25 * np.exp(-((X_temp-1)**2 + (Y_temp-2)**2)/3) +
20 * np.exp(-(X_temp**2 + Y_temp**2)/8))
cs2 = axes[0, 1].contourf(X_temp, Y_temp, Z_temp,
levels=15, cmap='hot')
axes[0, 1].set_title('温度分布等高线图')
axes[0, 1].set_xlabel('X坐标(m)')
axes[0, 1].set_ylabel('Y坐标(m)')
plt.colorbar(cs2, ax=axes[0, 1], label='温度(°C)')
# 3. 概率密度图
# 创建二维正态分布
from scipy.stats import multivariate_normal
x_prob = np.linspace(-4, 4, 100)
y_prob = np.linspace(-4, 4, 100)
X_prob, Y_prob = np.meshgrid(x_prob, y_prob)
pos = np.dstack((X_prob, Y_prob))
# 多个正态分布的混合
rv1 = multivariate_normal([0, 0], [[1, 0.5], [0.5, 1]])
rv2 = multivariate_normal([2, -1], [[0.5, 0], [0, 0.5]])
Z_prob = 0.6 * rv1.pdf(pos) + 0.4 * rv2.pdf(pos)
cs3 = axes[1, 0].contourf(X_prob, Y_prob, Z_prob,
levels=20, cmap='Blues')
contour_lines3 = axes[1, 0].contour(X_prob, Y_prob, Z_prob,
levels=10, colors='darkblue', linewidths=1)
axes[1, 0].set_title('概率密度等高线图')
axes[1, 0].set_xlabel('X')
axes[1, 0].set_ylabel('Y')
plt.colorbar(cs3, ax=axes[1, 0], label='概率密度')
# 4. 函数优化可视化
# Rosenbrock函数
x_opt = np.linspace(-2, 2, 100)
y_opt = np.linspace(-1, 3, 100)
X_opt, Y_opt = np.meshgrid(x_opt, y_opt)
Z_opt = (1 - X_opt)**2 + 100 * (Y_opt - X_opt**2)**2
# 使用对数尺度以便更好地显示
Z_opt_log = np.log10(Z_opt + 1)
cs4 = axes[1, 1].contourf(X_opt, Y_opt, Z_opt_log,
levels=20, cmap='viridis')
contour_lines4 = axes[1, 1].contour(X_opt, Y_opt, Z_opt_log,
levels=10, colors='white', linewidths=0.5)
# 标记全局最小值
axes[1, 1].plot(1, 1, 'r*', markersize=15, label='全局最小值')
axes[1, 1].set_title('Rosenbrock函数等高线图')
axes[1, 1].set_xlabel('X')
axes[1, 1].set_ylabel('Y')
axes[1, 1].legend()
plt.colorbar(cs4, ax=axes[1, 1], label='log10(f(x,y)+1)')
plt.tight_layout()
plt.show()
# 使用示例
contour_demo = ContourDemo()
contour_demo.basic_contour()
contour_demo.advanced_contour()
contour_demo.contour_applications()
4.2 3D图表
4.2.1 3D散点图与线图
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.colors import LinearSegmentedColormap
class Plot3DDemo:
"""3D图表演示类"""
def __init__(self):
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
# 生成示例数据
np.random.seed(42)
self.n_points = 100
self.x = np.random.randn(self.n_points)
self.y = np.random.randn(self.n_points)
self.z = self.x**2 + self.y**2 + np.random.randn(self.n_points) * 0.1
# 参数方程数据
self.t = np.linspace(0, 4*np.pi, 200)
self.x_param = np.sin(self.t)
self.y_param = np.cos(self.t)
self.z_param = self.t / (4*np.pi)
def basic_3d_plots(self):
"""基本3D图表"""
fig = plt.figure(figsize=(20, 15))
# 1. 3D散点图
ax1 = fig.add_subplot(2, 3, 1, projection='3d')
scatter = ax1.scatter(self.x, self.y, self.z, c=self.z,
cmap='viridis', s=50, alpha=0.7)
ax1.set_title('3D散点图')
ax1.set_xlabel('X轴')
ax1.set_ylabel('Y轴')
ax1.set_zlabel('Z轴')
plt.colorbar(scatter, ax=ax1, shrink=0.8)
# 2. 3D线图
ax2 = fig.add_subplot(2, 3, 2, projection='3d')
ax2.plot(self.x_param, self.y_param, self.z_param,
'b-', linewidth=2, alpha=0.8)
ax2.set_title('3D螺旋线图')
ax2.set_xlabel('X轴')
ax2.set_ylabel('Y轴')
ax2.set_zlabel('Z轴')
# 3. 3D柱状图
ax3 = fig.add_subplot(2, 3, 3, projection='3d')
# 创建柱状图数据
xpos = np.arange(5)
ypos = np.arange(4)
xposM, yposM = np.meshgrid(xpos, ypos)
xpos = xposM.ravel()
ypos = yposM.ravel()
zpos = np.zeros_like(xpos)
dx = dy = 0.8
dz = np.random.randint(1, 10, size=len(xpos))
colors = plt.cm.viridis(dz / float(dz.max()))
ax3.bar3d(xpos, ypos, zpos, dx, dy, dz, color=colors, alpha=0.8)
ax3.set_title('3D柱状图')
ax3.set_xlabel('X轴')
ax3.set_ylabel('Y轴')
ax3.set_zlabel('Z轴')
# 4. 3D表面图
ax4 = fig.add_subplot(2, 3, 4, projection='3d')
x_surf = np.linspace(-3, 3, 30)
y_surf = np.linspace(-3, 3, 30)
X_surf, Y_surf = np.meshgrid(x_surf, y_surf)
Z_surf = np.sin(np.sqrt(X_surf**2 + Y_surf**2))
surf = ax4.plot_surface(X_surf, Y_surf, Z_surf,
cmap='coolwarm', alpha=0.8)
ax4.set_title('3D表面图')
ax4.set_xlabel('X轴')
ax4.set_ylabel('Y轴')
ax4.set_zlabel('Z轴')
plt.colorbar(surf, ax=ax4, shrink=0.8)
# 5. 3D线框图
ax5 = fig.add_subplot(2, 3, 5, projection='3d')
wireframe = ax5.plot_wireframe(X_surf, Y_surf, Z_surf,
color='blue', alpha=0.7)
ax5.set_title('3D线框图')
ax5.set_xlabel('X轴')
ax5.set_ylabel('Y轴')
ax5.set_zlabel('Z轴')
# 6. 3D等高线图
ax6 = fig.add_subplot(2, 3, 6, projection='3d')
# 在不同高度绘制等高线
contours = ax6.contour(X_surf, Y_surf, Z_surf,
zdir='z', offset=-1.5, cmap='viridis')
contours = ax6.contour(X_surf, Y_surf, Z_surf,
zdir='x', offset=-3, cmap='viridis')
contours = ax6.contour(X_surf, Y_surf, Z_surf,
zdir='y', offset=3, cmap='viridis')
ax6.set_title('3D等高线投影')
ax6.set_xlabel('X轴')
ax6.set_ylabel('Y轴')
ax6.set_zlabel('Z轴')
ax6.set_xlim(-3, 3)
ax6.set_ylim(-3, 3)
ax6.set_zlim(-1.5, 1)
plt.tight_layout()
plt.show()
def advanced_3d_plots(self):
"""高级3D图表"""
fig = plt.figure(figsize=(20, 15))
# 1. 多层3D表面
ax1 = fig.add_subplot(2, 3, 1, projection='3d')
x = np.linspace(-2, 2, 50)
y = np.linspace(-2, 2, 50)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-(X**2 + Y**2))
Z2 = np.exp(-((X-1)**2 + (Y-1)**2)) * 0.5
surf1 = ax1.plot_surface(X, Y, Z1, alpha=0.7, cmap='Reds')
surf2 = ax1.plot_surface(X, Y, Z2, alpha=0.7, cmap='Blues')
ax1.set_title('多层3D表面')
ax1.set_xlabel('X轴')
ax1.set_ylabel('Y轴')
ax1.set_zlabel('Z轴')
# 2. 3D向量场
ax2 = fig.add_subplot(2, 3, 2, projection='3d')
# 创建向量场数据
x_vec = np.linspace(-2, 2, 8)
y_vec = np.linspace(-2, 2, 8)
z_vec = np.linspace(-2, 2, 8)
X_vec, Y_vec, Z_vec = np.meshgrid(x_vec, y_vec, z_vec)
# 向量分量
U = -Y_vec
V = X_vec
W = np.zeros_like(X_vec)
ax2.quiver(X_vec, Y_vec, Z_vec, U, V, W,
length=0.3, normalize=True, alpha=0.7)
ax2.set_title('3D向量场')
ax2.set_xlabel('X轴')
ax2.set_ylabel('Y轴')
ax2.set_zlabel('Z轴')
# 3. 参数化3D曲面
ax3 = fig.add_subplot(2, 3, 3, projection='3d')
# 创建球面
u = np.linspace(0, 2 * np.pi, 50)
v = np.linspace(0, np.pi, 50)
U, V = np.meshgrid(u, v)
X_sphere = np.cos(U) * np.sin(V)
Y_sphere = np.sin(U) * np.sin(V)
Z_sphere = np.cos(V)
# 根据位置着色
colors = Z_sphere
surf3 = ax3.plot_surface(X_sphere, Y_sphere, Z_sphere,
facecolors=plt.cm.viridis(colors),
alpha=0.8)
ax3.set_title('参数化球面')
ax3.set_xlabel('X轴')
ax3.set_ylabel('Y轴')
ax3.set_zlabel('Z轴')
# 4. 3D数据点云
ax4 = fig.add_subplot(2, 3, 4, projection='3d')
# 生成聚类数据
n_clusters = 3
n_points_per_cluster = 50
colors = ['red', 'blue', 'green']
for i in range(n_clusters):
center = np.random.randn(3) * 2
cluster_points = np.random.randn(n_points_per_cluster, 3) * 0.5 + center
ax4.scatter(cluster_points[:, 0], cluster_points[:, 1],
cluster_points[:, 2], c=colors[i],
s=30, alpha=0.7, label=f'聚类{i+1}')
ax4.set_title('3D点云聚类')
ax4.set_xlabel('X轴')
ax4.set_ylabel('Y轴')
ax4.set_zlabel('Z轴')
ax4.legend()
# 5. 3D动画轨迹
ax5 = fig.add_subplot(2, 3, 5, projection='3d')
# 创建复杂轨迹
t = np.linspace(0, 6*np.pi, 300)
x_traj = np.sin(t) * (1 + 0.5*np.cos(5*t))
y_traj = np.cos(t) * (1 + 0.5*np.cos(5*t))
z_traj = t / (3*np.pi)
# 使用颜色表示时间
colors_traj = plt.cm.plasma(t / t.max())
for i in range(len(t)-1):
ax5.plot([x_traj[i], x_traj[i+1]],
[y_traj[i], y_traj[i+1]],
[z_traj[i], z_traj[i+1]],
color=colors_traj[i], linewidth=2)
ax5.set_title('3D复杂轨迹')
ax5.set_xlabel('X轴')
ax5.set_ylabel('Y轴')
ax5.set_zlabel('Z轴')
# 6. 3D体积渲染
ax6 = fig.add_subplot(2, 3, 6, projection='3d')
# 创建3D体积数据
x_vol = np.linspace(-1, 1, 20)
y_vol = np.linspace(-1, 1, 20)
z_vol = np.linspace(-1, 1, 20)
X_vol, Y_vol, Z_vol = np.meshgrid(x_vol, y_vol, z_vol)
# 创建球形体积
volume = (X_vol**2 + Y_vol**2 + Z_vol**2) <= 1
# 只显示表面点
surface_points = np.where(volume)
ax6.scatter(X_vol[surface_points], Y_vol[surface_points],
Z_vol[surface_points], c=Z_vol[surface_points],
cmap='viridis', s=1, alpha=0.1)
ax6.set_title('3D体积渲染')
ax6.set_xlabel('X轴')
ax6.set_ylabel('Y轴')
ax6.set_zlabel('Z轴')
plt.tight_layout()
plt.show()
def interactive_3d_demo(self):
"""交互式3D演示"""
fig = plt.figure(figsize=(15, 10))
# 创建可旋转的3D图
ax = fig.add_subplot(111, projection='3d')
# 创建复杂的3D数据
phi = np.linspace(0, 2*np.pi, 50)
theta = np.linspace(0, np.pi, 50)
PHI, THETA = np.meshgrid(phi, theta)
# 创建变形球面
R = 1 + 0.3 * np.sin(5*PHI) * np.cos(5*THETA)
X = R * np.sin(THETA) * np.cos(PHI)
Y = R * np.sin(THETA) * np.sin(PHI)
Z = R * np.cos(THETA)
# 根据位置创建颜色
colors = np.sqrt(X**2 + Y**2 + Z**2)
surf = ax.plot_surface(X, Y, Z, facecolors=plt.cm.viridis(colors/colors.max()),
alpha=0.8, linewidth=0, antialiased=True)
# 添加一些装饰性的线条
for i in range(0, 50, 5):
ax.plot(X[i, :], Y[i, :], Z[i, :], 'k-', alpha=0.3, linewidth=0.5)
ax.plot(X[:, i], Y[:, i], Z[:, i], 'k-', alpha=0.3, linewidth=0.5)
ax.set_title('交互式3D变形球面', fontsize=16, fontweight='bold')
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')
# 设置视角
ax.view_init(elev=20, azim=45)
# 移除坐标轴背景
ax.xaxis.pane.fill = False
ax.yaxis.pane.fill = False
ax.zaxis.pane.fill = False
# 设置坐标轴线条透明度
ax.xaxis.pane.set_edgecolor('w')
ax.yaxis.pane.set_edgecolor('w')
ax.zaxis.pane.set_edgecolor('w')
ax.xaxis.pane.set_alpha(0.1)
ax.yaxis.pane.set_alpha(0.1)
ax.zaxis.pane.set_alpha(0.1)
plt.tight_layout()
plt.show()
# 使用示例
plot3d_demo = Plot3DDemo()
plot3d_demo.basic_3d_plots()
plot3d_demo.advanced_3d_plots()
plot3d_demo.interactive_3d_demo()