![image]()
import matplotlib.pyplot as plt
import numpy as np
# 设置字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
fig = plt.figure(figsize=(10, 8), dpi=150)
ax = fig.add_subplot(111, projection='3d')
ax.set_axis_off()
# 定义不同性质曲线的颜色
color_surface = '#1f77b4' # 曲面轮廓线:蓝色
color_axis = 'black' # 坐标轴:黑色
color_boundary = '#d62728' # 边界线 (y=a 与斜线):红色
color_shadow = '#7f7f7f' # 阴影区域:灰色
color_intersect = '#6a0dad' # 曲面截交线:深紫色
# ================= 1. 设定视角 =================
ax.view_init(elev=25, azim=-45)
# ================= 2. 绘制挺拔的二维正态分布曲面 =================
peak_z = 4.2 # 峰值高度
sigma = 2.2 # 扩散范围
# 2.1 水平闭环圆
theta = np.linspace(0, 2*np.pi, 100)
levels = [ 0.3, 1.8, ]
for level in levels:
r = sigma * np.sqrt(-2 * np.log(level / peak_z))
x_c = r * np.cos(theta)
y_c = r * np.sin(theta)
z_c = np.full_like(x_c, level)
ax.plot(x_c, y_c, z_c, color=color_surface, lw=1)
# 2.2 交叉截线
t = np.linspace(-8.0, 8.0, 100)
z_curve = peak_z * np.exp(-t**2 / (2 * sigma**2))
ax.plot(t, np.zeros_like(t), z_curve, color=color_surface, lw=1)
ax.plot(np.zeros_like(t), t, z_curve, color=color_surface, lw=1)
# ================= 3. 绘制坐标轴 =================
# p(y, y') 垂直轴:加长到 6.5
ax.quiver(0, 0, 0, 0, 0, 6.5, color=color_axis, lw=1.5, arrow_length_ratio=0.1)
ax.text(0, 0, 6.8, r"$p(y, \dot{y})$", fontsize=16, fontfamily='serif', ha='center')
# y 轴:箭头指向负 y 方向,长度保持 8.0
ax.quiver(0, 0, 0, 0, -8.0, 0, color=color_axis, lw=1, arrow_length_ratio=0.1)
ax.plot([0, 0], [0, 8.0], [0, 0], color=color_axis, lw=1)
ax.text(0, -8.5, 0, r"$y$", fontsize=16, fontfamily='serif')
# y' 轴:长度保持 8.0
ax.quiver(0, 0, 0, 8.0, 0, 0, color=color_axis, lw=1, arrow_length_ratio=0.1)
ax.plot([-8.0, 0], [0, 0], [0, 0], color=color_axis, lw=1)
ax.text(8.5, 0, 0, r"$\dot{y}$", fontsize=16, fontfamily='serif')
# ================= 4. 绘制底面的两条边界线与阴影 =================
a_val = -4.0
# 4.1 平行于 y' 轴的直线 y = a
x_line_a = np.linspace(0, 6.0, 50)
y_line_a = np.full_like(x_line_a, a_val)
z_line_a = np.zeros_like(x_line_a)
ax.plot(x_line_a, y_line_a, z_line_a, color=color_boundary, lw=2.5)
# 4.2 斜线
slope = 0.15
y_line_slope = a_val + slope * x_line_a
ax.plot(x_line_a, y_line_slope, z_line_a, color=color_boundary, lw=2.5, ls='--')
# 4.3 阴影区域
for x_val in np.linspace(0, 4.0, 30):
y_start = a_val
y_end = a_val + slope * x_val
ax.plot([x_val, x_val], [y_start, y_end], [0.01, 0.01], color=color_shadow, lw=1)
# ================= 5. 绘制曲面上的截交线 =================
# 5.1 平面 y=a 的截交线
x_cross_a = np.linspace(0, 6.0, 100)
y_cross_a = np.full_like(x_cross_a, a_val)
z_cross_a = peak_z * np.exp(-(x_cross_a**2 + a_val**2) / (2 * sigma**2))
ax.plot(x_cross_a, y_cross_a, z_cross_a, color=color_intersect, lw=2.5)
ax.plot([0, 0], [a_val, a_val], [0, z_cross_a[0]], color=color_intersect, lw=2.5)
ax.plot([6, 6], [a_val, a_val], [z_cross_a[-1], 0], color=color_intersect, lw=2.5)
# 5.2 斜线平面的截交线
x_cross_slope = np.linspace(0, 6.0, 100)
y_cross_slope = a_val + slope * x_cross_slope
z_cross_slope = peak_z * np.exp(-(x_cross_slope**2 + y_cross_slope**2) / (2 * sigma**2))
ax.plot(x_cross_slope, y_cross_slope, z_cross_slope, color=color_intersect, lw=2.5, ls='--')
ax.plot([0, 0], [a_val, a_val], [0, z_cross_slope[0]], color=color_intersect, lw=2.5, ls='--')
ax.plot([6, 6], [y_cross_slope[-1], y_cross_slope[-1]], [z_cross_slope[-1], 0], color=color_intersect, lw=2.5, ls='--')
# ================= 6. 标注 =================
ax.scatter(0, a_val, 0, color=color_boundary, s=25)
ax.text(0, a_val - 0.5, 0, r"$a$", fontsize=16, fontfamily='serif')
ax.text(4, a_val - 1.5, 0, r"$y=a$", fontsize=14, fontfamily='serif')
ax.text(0.5, a_val + 0.4, 0, r"$\alpha$", fontsize=16, fontfamily='serif')
ax.text2D(0.05, 0.9, r"$(a)$", transform=ax.transAxes, fontsize=18, fontfamily='serif')
# 坐标轴显示范围 (z 轴拉长,需同步增大 zlim)
ax.set_xlim([-4.0, 4.0])
ax.set_ylim([-4.0, 4.0])
ax.set_zlim([0, 6.5])
plt.tight_layout()
plt.show()