【MCM】(x= (N_A),y=(N_G),z=(p))RGB=T*

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap, Normalize

# -----------------------------
# Parameters
# -----------------------------
M = 1e8
H = 3
Q_h = 179000
Q_E = H * Q_h

# Data ranges
NA_vals = np.logspace(2, 6, 30)        # >0
NG_vals = np.logspace(2, 6, 30)        # >0
p_vals  = np.linspace(100, 150, 6)     # >0

NA_grid, NG_grid, p_grid = np.meshgrid(NA_vals, NG_vals, p_vals, indexing='ij')
NA = NA_grid.ravel()
NG = NG_grid.ravel()
p  = p_grid.ravel()

# Completion time
R = p * NG + np.minimum(Q_E, p * NA)
T = M / R

# Clip for readable coloring
T_clip_max = 50.0
T_plot = np.clip(T, 0, T_clip_max)

# Colormap: red (short) -> purple (long)
cmap = LinearSegmentedColormap.from_list("red_to_purple", ["red", "purple"])
norm = Normalize(vmin=np.min(T_plot), vmax=np.max(T_plot))

# -----------------------------
# Plot with visible origin + axis rays
# Use orthographic (axonometric) and symlog so 0 is representable.
# -----------------------------
fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111, projection='3d')

ax.set_proj_type('ortho')
ax.view_init(elev=22, azim=45)

sc = ax.scatter(NA, NG, p, c=T_plot, cmap=cmap, norm=norm, s=10, alpha=0.75, depthshade=False)

# Use symlog so that we can show 0 and also cover wide ranges
ax.set_xscale('symlog', linthresh=1e3)
ax.set_yscale('symlog', linthresh=1e3)

NA_max = NA_vals.max()
NG_max = NG_vals.max()
p_max  = p_vals.max()

ax.set_xlim(0, NA_max)
ax.set_ylim(0, NG_max)
ax.set_zlim(0, p_max)

# Axis rays from origin
ax.plot([0, NA_max], [0, 0], [0, 0], linewidth=2)  # x-axis ray
ax.plot([0, 0], [0, NG_max], [0, 0], linewidth=2)  # y-axis ray
ax.plot([0, 0], [0, 0], [0, p_max], linewidth=2)   # z-axis ray

# Clean up the box/panes/grids so it doesn't look like a cube with diagonals
ax.grid(False)
for axis in (ax.xaxis, ax.yaxis, ax.zaxis):
    axis.pane.set_alpha(0.0)
    axis.pane.set_edgecolor((1, 1, 1, 0))
ax.set_frame_on(False)

ax.set_xlabel(r'$N_A$ (launches/year)')
ax.set_ylabel(r'$N_G$ (launches/year)')
ax.set_zlabel(r'$p$ (tons/launch)')

ax.set_title(
    "Axonometric 3D scatter with visible origin + axis rays\n"
    r"Color = completion time $T=M/[pN_G+\min(Q_E,pN_A)]$ (years), clipped at 50"
)

cbar = fig.colorbar(sc, ax=ax, pad=0.08, shrink=0.75)
cbar.set_label(r'$T$ (years)')

plt.tight_layout()
outpath = "/mnt/data/3d_axonometric_origin_axes.png"
plt.savefig(outpath, dpi=220)
plt.show()

outpath

明白了------你要的是**能看到"原点 + 三根坐标轴射线"**的斜二测/轴测图,而不是那个"立方体边框把视线挡住"的样子。

我已经重新画了一版:

  • 显式画出从 (0,0,0) 出发的三根轴射线(x= (N_A),y=(N_G),z=§)
  • 去掉了立方体框、网格和面板,避免遮挡
  • 因为 (N_A,N_G) 跨很多数量级,但你又要看到原点,所以我用 symlog(能包含 0,同时保持对数尺度的可读性)

下载:带原点与三轴射线的斜二测 3D 图

如果你希望 z 轴也从 100 开始(因为 (p\ge100)),把原点改成 ((0,0,100)) 作为"物理原点",我也可以给你再画一版(轴射线从 (p=100) 起)。

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap, Normalize

# Parameters
M = 1e8
H = 3
Q_h = 179000
Q_E = H * Q_h

# Ranges
NA_vals = np.logspace(2, 6, 30)
NG_vals = np.logspace(2, 6, 30)
p_vals  = np.linspace(100, 150, 6)

NA_grid, NG_grid, p_grid = np.meshgrid(NA_vals, NG_vals, p_vals, indexing='ij')
NA = NA_grid.ravel()
NG = NG_grid.ravel()
p  = p_grid.ravel()

R = p * NG + np.minimum(Q_E, p * NA)
T = M / R

T_clip_max = 50.0
T_plot = np.clip(T, 0, T_clip_max)

cmap = LinearSegmentedColormap.from_list("red_to_purple", ["red", "purple"])
norm = Normalize(vmin=np.min(T_plot), vmax=np.max(T_plot))

# Plot
fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111, projection='3d')

ax.set_proj_type('ortho')
ax.view_init(elev=22, azim=45)

sc = ax.scatter(NA, NG, p, c=T_plot, cmap=cmap, norm=norm, s=10, alpha=0.75, depthshade=False)

# Show 0 for NA/NG, and start z from 100
ax.set_xscale('symlog', linthresh=1e3)
ax.set_yscale('symlog', linthresh=1e3)

NA_max = NA_vals.max()
NG_max = NG_vals.max()
p_min  = 100.0
p_max  = p_vals.max()

ax.set_xlim(0, NA_max)
ax.set_ylim(0, NG_max)
ax.set_zlim(p_min, p_max)

# "Physical origin" at (0,0,100)
x0, y0, z0 = 0.0, 0.0, p_min

# Axis rays from (0,0,100)
ax.plot([x0, NA_max], [y0, y0], [z0, z0], linewidth=2)  # x-axis ray
ax.plot([x0, x0], [y0, NG_max], [z0, z0], linewidth=2)  # y-axis ray
ax.plot([x0, x0], [y0, y0], [z0, p_max], linewidth=2)   # z-axis ray

# Mark the physical origin
ax.scatter([x0], [y0], [z0], s=40)

# Clean up box/panes
ax.grid(False)
for axis in (ax.xaxis, ax.yaxis, ax.zaxis):
    axis.pane.set_alpha(0.0)
    axis.pane.set_edgecolor((1, 1, 1, 0))
ax.set_frame_on(False)

ax.set_xlabel(r'$N_A$ (launches/year)')
ax.set_ylabel(r'$N_G$ (launches/year)')
ax.set_zlabel(r'$p$ (tons/launch)')

ax.set_title(
    "Axonometric 3D scatter with axis rays from (0,0,100)\n"
    r"Color = completion time $T=M/[pN_G+\min(Q_E,pN_A)]$ (years), clipped at 50"
)

cbar = fig.colorbar(sc, ax=ax, pad=0.08, shrink=0.75)
cbar.set_label(r'$T$ (years)')

plt.tight_layout()
outpath = "/mnt/data/3d_axonometric_origin_axes_z100.png"
plt.savefig(outpath, dpi=220)
plt.show()

outpath
相关推荐
SamChan9017 小时前
用Playwright端到端测试PDF翻译功能:Web自动化测试实战
前端·python·ai·pdf·wpf
AI英德西牛仔18 小时前
千问导出 pdf 颜色不一样怎么办,选用 AI 导出鸭优化格式转换,多维度剖析千问内容 PDF 变色各类成因
人工智能·ai·chatgpt·pdf·deepseek·ai导出鸭
赵广陆1 天前
企业实战:主体识别
langchain·pdf·langgraph
AI英德西牛仔1 天前
豆包导出 pdf 颜色不一样怎么办,选用 AI 导出鸭优化文档导出,结合行业白皮书数据解析色彩失真成因
人工智能·ai·chatgpt·pdf·deepseek·ai导出鸭
薰珞婷紫小亭子2 天前
如何解决IEEE期刊LaTeX 模版编译pdf出现大空白的问题
经验分享·pdf
Hello-FPGA2 天前
AI 如何自动通过 PDF 原理图生成管脚映射
人工智能·fpga开发·pdf
阿部多瑞 ABU2 天前
告别手工核图:基于 .NET + MuPDFCore 的 CAD 等轴测 PDF 材料表提取与新旧版本对比实战
后端·算法·ui·pdf·c#
2601_963906783 天前
可自由切割与合并的 PDF 尺寸调整与打印工具
pdf
2601_965912913 天前
PDF转Word与拆分组合操作实测:从格式保真到批量处理的方案对比
pdf·word
海兰3 天前
【应用】ClawPDF 完全指南:安装、部署与使用
人工智能·pdf·openclaw