基于GetDist的三角图等高线重叠逻辑复刻与优化问询
解决GetDist三角图等高线重叠与zorder配置问题
我刚搞定过几乎一模一样的GetDist三角图需求,给你一套亲测有效的方案,完美实现你要的重叠逻辑:
核心思路
要实现「最优(最小面积)样本填充不被覆盖,所有轮廓线都可见」,关键是分层管理zorder+按面积排序绘制:
- 填充层:按面积从大到小(最差→最优)的顺序绘制,让最优样本的填充落在最上层,完全不被遮挡;
- 轮廓线层:统一放在所有填充层的上方,用透明度保证所有轮廓线都能显示,不会被填充或其他轮廓线遮挡。
具体实现步骤
1. 计算椭圆面积(或直接用FoM排序)
因为FoM和椭圆面积成反比,你可以直接用已知的FoM排序,也可以通过协方差矩阵计算面积(针对二维参数对):
import numpy as np def get_ellipse_area(cov): # 计算2x2协方差对应的椭圆面积:π*sqrt(行列式) det = np.linalg.det(cov) return np.pi * np.sqrt(det) if det > 0 else float('inf')
然后把你的样本信息整理成列表,带上协方差、颜色、FoM(或计算面积):
# 替换成你自己的实际数据 sample_list = [ {"cov": cov_yellow, "fill1": "#FFE000", "fill2": "#FFF280", "line": "#D4A000", "fom": 12.5}, # 最优,面积最小 {"cov": cov_orange, "fill1": "#FF9A00", "fill2": "#FFC260", "line": "#CC7A00", "fom": 9.2}, {"cov": cov_red, "fill1": "#FF3333", "fill2": "#FF8080", "line": "#CC2929", "fom": 6.8}, {"cov": cov_purple, "fill1": "#9933FF", "fill2": "#C280FF", "line": "#7A29CC", "fom": 4.5}, {"cov": cov_darkblue, "fill1": "#003399", "fill2": "#6080CC", "line": "#002673", "fom": 2.1}, # 最差,面积最大 ] # 按FoM从大到小排序(等价于面积从小到大) sorted_samples = sorted(sample_list, key=lambda x: x["fom"], reverse=True)
2. 分层绘制填充与轮廓线
先绘制所有填充层(从最差到最优,保证最优填充在最上层),再绘制所有轮廓线(统一高zorder,确保在填充上方):
from getdist import plots, Analytic # 创建三角图绘图对象 g = plots.get_subplot_plotter() # --- 第一步:绘制填充层 --- # 反转排序,先画最差的(面积最大),后画最优的(面积最小) for idx, sample in enumerate(reversed(sorted_samples)): # 创建Analytic对象(替换成你的参数均值,这里用全0示例) analytic = Analytic(mean=np.zeros(len(sample["cov"])), cov=sample["cov"]) # 绘制2σ浅色填充,zorder从10开始递增 g.add_analytic(analytic, color=sample["fill2"], filled=True, alpha=1.0, zorder=10 + idx) # 绘制1σ深色填充,zorder比同组2σ高10,确保同一组内1σ在2σ上方 g.add_analytic(analytic, color=sample["fill1"], filled=True, alpha=1.0, zorder=20 + idx) # --- 第二步:绘制轮廓线层 --- # 所有轮廓线zorder设为100+,保证在所有填充层上方,同时设置透明度 for sample in sorted_samples: analytic = Analytic(mean=np.zeros(len(sample["cov"])), cov=sample["cov"]) # 2σ轮廓线,alpha设为0.6(透明) g.add_analytic(analytic, color=sample["line"], filled=False, contour_levels=[2], alpha=0.6, zorder=100) # 1σ轮廓线,alpha设为0.8(比2σ稍不透明),zorder比2σ高1 g.add_analytic(analytic, color=sample["line"], filled=False, contour_levels=[1], alpha=0.8, zorder=101) # 最后绘制三角图的其他元素(参数标签等) g.triangle_plot([], filled=False, title_limit=1) # 这里根据你的实际需求调整
关键细节说明
- GetDist默认zorder规则:默认是按绘制顺序自动递增,后绘制的元素zorder更高,会覆盖之前的。所以之前手动设置zorder混乱,大概率是绘制顺序搞反了。
- 轮廓线的contour_levels:1对应68% C.L(1σ),2对应95% C.L(2σ),这是GetDist的默认映射。
- 透明度设置:填充用
alpha=1.0保证纯色不透明,轮廓线用alpha=0.6-0.8保证所有轮廓线都能透过彼此看到。
这样配置后,黄色(最优)的填充会完全覆盖下层的其他填充,同时所有样本的1σ/2σ轮廓线都清晰可见,完美匹配你要的效果。
内容的提问来源于stack exchange,提问作者user1773603
相关产品推荐
相关产品推荐

