如何获取理想的Matplotlib 3D绘图样式?复制代码未达预期
解决Matplotlib 3D绘图样式不符合预期的问题
嘿,我看你贴的代码后半段被截断了(np....那里没写完),而且目前的代码只生成了数据和网格,还没完成3D绘图的核心步骤——计算对应网格的Z值并绘制曲面/散点,这应该就是你得不到理想3D图的原因。我来帮你补全并优化这段代码,实现预期的3D可视化效果~
完整修正后的代码
#!/usr/bin/env python import numpy as np import scipy.linalg from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt # 生成三维多元正态分布数据 mean = np.array([0.0, 0.0, 0.0]) cov = np.array([[1.0, -0.5, 0.8], [-0.5, 1.1, 0.0], [0.8, 0.0, 1.0]]) data = np.random.multivariate_normal(mean, cov, 50) # 覆盖数据域的规则网格(补全截断部分) X, Y = np.meshgrid(np.arange(-3.0, 3.0, 0.5), np.arange(-3.0, 3.0, 0.5)) n_samples = X.shape[0] * X.shape[1] # 将网格转换为二维数组,用于计算多元高斯密度 XY = np.column_stack([X.reshape(n_samples), Y.reshape(n_samples)]) # 计算多元正态分布在网格点上的Z值(概率密度) inv_cov = scipy.linalg.inv(cov) det_cov = scipy.linalg.det(cov) Z = [] for xy in XY: # 计算(x - mean)的转置乘以逆协方差再乘以(x - mean) diff = xy - mean[:2] exponent = -0.5 * np.dot(np.dot(diff.T, inv_cov[:2, :2]), diff) density = (1.0 / (np.sqrt((2 * np.pi)**2 * np.linalg.det(cov[:2, :2])))) * np.exp(exponent) Z.append(density) Z = np.array(Z).reshape(X.shape) # 创建3D绘图 fig = plt.figure(figsize=(10, 8)) ax = fig.add_subplot(111, projection='3d') # 绘制原始数据散点 ax.scatter(data[:, 0], data[:, 1], data[:, 2], c='r', marker='o', label='Sample Data') # 绘制3D概率密度曲面 ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.7, label='Gaussian Density') # 设置绘图样式 ax.set_xlabel('X Axis') ax.set_ylabel('Y Axis') ax.set_zlabel('Z Axis') ax.set_title('3D Visualization of Multivariate Normal Distribution') ax.legend() # 调整视角,让图形更清晰 ax.view_init(elev=30, azim=45) plt.show()
关键优化点说明
- 补全网格定义:把你截断的
np....补成完整的np.arange(-3.0, 3.0, 0.5),确保X和Y网格覆盖数据的合理范围 - 计算Z值:根据多元正态分布的概率密度公式,计算网格点对应的Z值,这是绘制3D曲面的核心
- 添加可视化元素:同时绘制原始数据散点和拟合的密度曲面,让图的信息更完整
- 样式调整:设置颜色映射(
cmap='viridis')、透明度(alpha=0.7),调整视角(view_init),添加标签和图例,让3D图更美观易读
如果你的预期样式不是概率密度曲面,而是其他类型(比如PCA降维后的3D投影),可以告诉我具体需求,我再帮你调整~
内容的提问来源于stack exchange,提问作者James Wong




