4

在 python3 中,我使用工具GetDist 工具生成协方差矩阵的三元图时遇到了 2 个问题。

1)目前,我只需调用一次绘图函数(triangle_plot)就可以在同一个图形上绘制 2 个协方差矩阵。将要绘制的协方差矩阵列表指定为第一个输入足以具有每个矩阵的 (1 sigma,2 sigma) 轮廓。这里是由 2 个协方差矩阵生成的三元图示例(填充区域对应于 1 sigma 置信水平 (68%),阴影对应于 2 sigma CL (95%))。颜色标识每个矩阵(此处为红色和蓝色):

每个矩阵的轮廓 1 sigma 和 2 sigma

我的主要目标是我想通过这样的降序优先考虑重叠:

1) 1 sigma blue disk of smallest ellipse (blue)
2) 1 sigma red disk of largest ellipse (red)
3) 2 sigma blue disk of smallest ellipse (shaded blue)
4) 2 sigma red disk of smallest ellipse (shaded red)

而在默认行为中,我具有以下降序优先级:

1) 1 sigma blue disk of smallest ellipse (blue)
2) 2 sigma blue disk of smallest ellipse (shaded blue)
2) 1 sigma red disk of largest ellipse (red)
4) 2 sigma red disk of smallest ellipse (shaded red)

这里是生成上图的脚本:

g.triangle_plot([matrix1, matrix2],
                names,
                filled = True,                
                legend_labels = ['1240', '1560'],
                legend_loc = 'upper right',
                contour_colors = ['red','darkblue'],
                line_args = [{'lw':2, 'color':'red'},
                {'lw':2, 'color':'darkblue'}],
                )

最后,我只是希望 1 sigma 红色圆盘不要被 2 sigma 蓝色阴影所隐藏。

这是我想要的一个例子(注意,与我上面的三幅图相比,红色和蓝色之间存在反转):

想要的重叠示例

不要在意黄色的轮廓。如您所见,1 sigma 蓝色磁盘的优先级高于 2 红色阴影 sigma 磁盘。这与我想要的行为完全相同。

在我上面的三幅图中,我尝试了很多使用 alpha 参数的方法,但是由于颜色混合在一起并且不再与图例(红色和蓝色)相对应,所以它一团糟。

2)鉴于我没有发现在源代码中更改此优先级的事实GetDist,我尝试调用两次该函数triangle_plot,每次调用一个矩阵。

但不幸的是,在 2 次调用之后,2 个地块没有重叠。仅出现一个颜色三图(最后一次调用的那个)。例如,如果我像这样连续两次调用(matrix 2代表最大的红色椭圆和matrix1最小的椭圆):

g.triangle_plot([matrix2],
                names,
                filled = True,                
                legend_labels = ['1560'],
                legend_loc = 'upper right',
                contour_colors = ['darkblue'],
                contours = 0,
                num_plot_contours = 0,
                line_args = [{'lw':2, 'color':'darkblue'}]
                )

g.triangle_plot([matrix1],
                names,
                filled = True,                
                legend_labels = ['1240'],
                legend_loc = 'upper right',            
                contour_colors = ['red'],
                contours = 1,
                num_plot_contours = 1,
                line_args = [{'lw':2, 'color':'red'}]
                )

是否可以保留第一个三图(矩阵 2 以红色表示)并再次调用triangle_plot函数以重叠,在第一个三图上,第二个三图(蓝色)?

实际上,这将允许我使用 Confidence 级别的标识符(CL:68% 或 95%),然后解决这个优先级问题。

不幸的是,当我调用 2 次 triangle_plot 函数时,重叠不起作用:只保留最后一次调用,第一次调用似乎已从图中删除。

在这种三元图上强制重叠(重叠轮廓但不重叠标签和刻度)的方法是什么?我们可以先验地认为这很简单,因为三图只是框/子图),但我不能仅仅设法执行这种重叠。我试图在两个电话之间插入:

plt.show(block=False)  # do not block

但这不起作用。我认为这是因为我最后将图形保存在文件中:

# Save figure
g.fig.savefig('Comparison_Overlap.pdf')

更新 1

感谢史蒂夫。只是最后一个问题:水平和垂直 xticks 被轮廓和填充区域隐藏,我不知道后者是哪个zorder。这里有 2 个例子说明了这个问题:

xticks 蒙面的第一个例子

可以看到对应0.95的xtick被屏蔽了。

xticks 掩码的第二个示例

你可以看到右下角的 xtick 也被屏蔽了。

更新 2

完美的解决方案,@Stef但它仍然是一个小问题:xticks 和 yticks 被轮廓隐藏。

默认情况下,z-orderxticks 的 of 由下式给出:

g.fig.axes[0].xaxis.get_major_ticks()[0].zorder

返回:0

所以,当我绘制我的轮廓时,我把triangle_plot

for ax in g.fig.axes:
  geo = ax.get_geometry()
  if (geo[2]-1) // geo[0] > (geo[2]-1) % geo[0]:
    for c,z in zip(ax.collections, [-1.7, -1.5, -0.1, -1.6, -1.4, -0.1]):
      c.zorder = z

这样,我可以让轮廓不被轮廓隐藏。例如,如下所示:

xtick 没有隐藏

这个解决方案不是很容易,因为我必须处理负值 ( [-1.7, -1.5, -0.1, -1.6, -1.4, -0.1])。

现在,多亏了@Stef,我可以修改 的这个值 g.fig.axes[0].xaxis.get_major_ticks()[0].zorder,例如等于3

# Modify z-order 
for mt in g.fig.axes[0].xaxis.get_major_ticks():
  mt.zorder = 3
for mt in g.fig.axes[0].yaxis.get_major_ticks():
  mt.zorder = 3

但如果我在那之后做:

for ax in g.fig.axes:
  geo = ax.get_geometry()
  if (geo[2]-1) // geo[0] > (geo[2]-1) % geo[0]:
    for c,z in zip(ax.collections, [1.6, 1.8, 2, 1.7, 1.9, 2]):
      c.zorder = z

xticks 仍然被轮廓隐藏,而阈值设置为3:我不明白这种行为:

xtick 隐藏

可能有什么问题?

更新 3

在这里,我试图解决关于我想要在刻度上的优先级的问题的最后一件事,即使 xticks/yticks 出现在轮廓前面,而不是瞬间发生的相反。

zorder如果我默认打印get_major_ticks()and的值get_ticklines()[0]),我得到:

print('zorder1 = ', g.fig.axes[0].xaxis.get_major_ticks()[0].zorder)
print('zorder2 = ', g.fig.axes[0].xaxis.get_ticklines()[0].zorder)

==>

zorder1 =  0
zorder2 =  2.01

get_major_ticks()和有什么区别get_ticklines()

您可以理解为什么我可以设法在所有轮廓前面设置刻度,即通过在给出的解决方案中设置负值@Stef

for ax in g.fig.axes:
  geo = ax.get_geometry()
  if (geo[2]-1) // geo[0] > (geo[2]-1) % geo[0]:
    for c,z in zip(ax.collections, [-1.7, -1.5, -0.1, -1.6, -1.4, -0.1]):
      c.zorder = z

zorder2我可以通过放置来修改上述内容:

g.fig.axes[0].tick_params(zorder=3)

但我不可能修改zorder10默认情况下)。

我怎么能改变这个0zorder1(它引用get_ticklines())?

4

1 回答 1

2

这有点骇人听闻,但您可以在zorder之后更改轮廓。为此,我们采用下三角图并设置zorder路径和线集的属性。它们按以下顺序出现:

  1. 第一个样本的 2 sigma 的填充区域
  2. 第一个样本的 1 sigma 的填充区域
  3. 第一个样本的等高线
  4. 第二个样本的 2 sigma 的填充区域
  5. 第二个样本的 1 sigma 的填充区域
  6. 第二个样本的等高线

原来所有的填充区域都有zorder 1所有的线条2。我们根据需要将它们设置为例如17, 19, 21, 18, 20, 21

例子:

from getdist import plots, gaussian_mixtures
samples1, samples2 = gaussian_mixtures.randomTestMCSamples(ndim=4, nMCSamples=2)
g = plots.get_subplot_plotter()
g.triangle_plot([samples1, samples2], filled=True, legend_labels = ['Contour 1', 'Contour 2'])

for ax in g.fig.axes:
    geo = ax.get_geometry()
    if (geo[2]-1) // geo[0] > (geo[2]-1) % geo[0]:
       for c,z in zip(ax.collections, [17,19,21,18,20,21]):
           c.zorder = z 

在此处输入图像描述

于 2020-08-25T07:53:10.233 回答