【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
相关推荐
weixin_416667962 小时前
Stirling-PDF是一款完全开源免费、本地部署的全能PDF处理工具
pdf
开开心心就好3 小时前
PDF图片去水印软件,支持批量处理页面
前端·javascript·人工智能·智能手机·pdf·语音识别
2501_919749034 小时前
华为鸿蒙免费PDF工具—小羊免费PDF
华为·pdf·harmonyos·鸿蒙
SamChan904 小时前
PDF多语言翻译的格式还原技术拆解:从版面分析到内容重排的工程实现
python·ai·pdf·机器翻译
weixin_4692738118 小时前
如何在线把文字转为 pdf 文档
pdf
2601_9639067818 小时前
离线截图 OCR 识别:支持表格与 PDF 解析
pdf·ocr·软件需求
asdzx671 天前
Python 实现 PDF 文本查找与高亮标注
开发语言·python·pdf
laoban-yu1 天前
Word与PDF文档互转
pdf·word·文档转换
鲲穹AI种草3 天前
PDF 文档多格式转换处理,多款 PDF 处理工具能力客观记录
pdf·文档格式转换
Felicia-侧听3 天前
PDF怎么转换成OFD?在线PDF转OFD方法
pdf·pdf转换·ofd·电子发票·文件格式转换·pdf转ofd·ofd格式