穿越分析画图1

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'   # 阴影区域:灰色
# ================= 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,  3.0, ]
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 交叉截线 (沿 y=0 和 y'=0 的剖面线)
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)  # 沿 y' 轴
ax.plot(np.zeros_like(t), t, z_curve, color=color_surface, lw=1)  # 沿 y 轴
# ================= 3. 绘制完整坐标轴 (正负半轴都保留) =================
# p(y, y') 垂直轴 (为了配合更高的山峰,拉长垂直轴)
ax.quiver(0, 0, 0, 0, 0, 5.5, color=color_axis, lw=1.5, arrow_length_ratio=0.1)
ax.text(0, 0, 5.8, r"$p(y, \dot{y})$", fontsize=16, fontfamily='serif', ha='center')
# y 轴 (完整十字)
ax.quiver(0, 0, 0, -10.0, 0, 0, color=color_axis, lw=1, arrow_length_ratio=0.1)
ax.quiver(0, 0, 0, 10.0, 0, 0, color=color_axis, lw=1, arrow_length_ratio=0.1)
ax.text(-4.6, 0, 0, r"$y$", fontsize=16, fontfamily='serif')
# y' 轴 (完整十字)
ax.quiver(0, 0, 0, 0, -10.0, 0, color=color_axis, lw=1, arrow_length_ratio=0.1)
ax.quiver(0, 0, 0, 0, 10.0, 0, color=color_axis, lw=1, arrow_length_ratio=0.1)
ax.text(0, 4.5, 0, r"$\dot{y}$", fontsize=16, fontfamily='serif')
# ================= 4. 绘制底面的两条边界线与阴影 (仅 y' >= 0 区域) =================
a_val = -2.0  # 交点 'a' 位置
# 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 斜线 (从交点 'a' 出发)
slope = 0.3
x_line_slope = np.linspace(0, 6.0, 50)
y_line_slope = a_val + slope * x_line_slope
z_line_slope = np.zeros_like(x_line_slope)
ax.plot(x_line_slope, y_line_slope, z_line_slope, color=color_boundary, lw=2.5, ls='--')
# 4.3 阴影区域 (在两条线之间,仅 y' >= 0)
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)
# 4.4 标注
# 标记交点 a
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')
# 标记 y=a 线
ax.text(3.5, a_val - 0.5, 0, r"$y=a$", fontsize=14, fontfamily='serif')
# 标记 α 角
ax.text(1.0, a_val + 0.6, 0, r"$\alpha$", fontsize=16, fontfamily='serif')
# 左上角标号
ax.text2D(0.05, 0.9, r"$(a)$", transform=ax.transAxes, fontsize=18, fontfamily='serif')
ax.set_xlim([-4.5, 4.5])
ax.set_ylim([-4.5, 4.5])
ax.set_zlim([0, 5.5])
plt.tight_layout()
plt.show()
posted @ 2026-10-10 22:24  redufa  阅读(7)  评论(0)    收藏  举报