Matplotlib - Python- GetDist 工具 - 通过调用两次绘图函数重叠 2 个三角形图(三联图):两者之间的可见优先级问题
Matplotlib - Python- GetDist tool - Overlapping 2 triangle plots (triplots) by calling twice the plot function: issue of visible priority between both
在 python3 中,我在使用工具 GetDist
tool to produce triplot of covariance matrix.
时遇到了 2 个问题
1) 目前,我只需调用一次绘图函数 (triangle_plot) 就可以在同一张图上绘制 2 个协方差矩阵。将要绘制的协方差矩阵列表指定为第一个输入足以让每个矩阵具有 (1 sigma,2 sigma) 等高线。这里是一个由 2 个协方差矩阵生成的三重图示例(填充区域对应于 1 sigma 置信水平 (68%),阴影对应于 2 sigma C.L (95%))。颜色标识每个矩阵(此处为红色和蓝色):
我的主要目标是我想像这样按降序优先重叠:
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 西格玛红色圆盘不要被 2 西格玛蓝色阴影隐藏。
这是我想要的示例(注意,与上面的三联图相比,红色和蓝色之间存在反转):
不要在意黄色轮廓。如您所见,1 sigma 蓝色磁盘优先于 2 红色阴影 sigma 磁盘。这与我想要的行为完全相同。
在上面的三图中,我尝试了很多 alpha 参数,但由于颜色混合且不再与图例(红色和蓝色)对应,因此一团糟。
2) 鉴于我没有在 GetDist
的源代码中找到更改此优先级的事实,我尝试调用两次函数 triangle_plot
每次调用一个矩阵。
但不幸的是,2次调用后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
函数以重叠第一个三联图和第二个三联图(蓝色)?
事实上,这将允许我使用置信度标识符(C.L:68% 或 95%),然后解决这个优先级问题。
不幸的是,当我调用 2 次 triangle_plot 函数时,重叠不起作用:只保留最后一次调用,第一次调用似乎已从图中删除。
在这种三联图中强制重叠的方法是什么(重叠等高线但不重叠标签和刻度)?我们可以先验地认为这很简单,因为三联图只是 boxes/subplots) 但我不能仅仅设法执行这种重叠。我试图在两个调用之间插入:
plt.show(block=False) # do not block
但这不起作用。我认为这是因为我在最后将图形保存在文件中:
# Save figure
g.fig.savefig('Comparison_Overlap.pdf')
更新 1
感谢 Stef。最后一个问题:水平和垂直 xticks 被轮廓和填充区域隐藏,我不知道后者是 zorder
哪个。这里有 2 个例子说明了这个问题:
可以看到0.95对应的xtick被mask了
可以看到右下角的xtick也被屏蔽了
更新 2
@Stef
的解决方案完美运行,但仍然存在一个小问题:xticks 和 yticks 被轮廓隐藏了。
默认情况下,xticks 的 z-order
of 由 :
给出
g.fig.axes[0].xaxis.get_major_ticks()[0].zorder
那个 returns : 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
这样,我可以让轮廓不被轮廓隐藏。例如,如下所示:
这个解决方案不是很容易,因为我必须处理负值 ([-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
:我不明白这种行为:
可能出了什么问题?
更新 3
这是我试图解决关于我想要的刻度优先级问题的最后一件事,即让 xticks/yticks 出现在轮廓前面,而不是即时出现的相反部分。
如果我默认打印 get_major_ticks()
和 get_ticklines()[0])
的值 zorder
,我得到:
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)
但我无法修改 zorder1
(默认等于 0
)。
如何更改 zorder1
的 0
值(引用 get_ticklines()
)?
这有点老套,但您可以稍后更改轮廓的 zorder
。为此,我们采用下三角图并设置路径和线集合的 zorder
属性。它们按以下顺序出现:
- 第一个样本的 2 sigma 的填充区域
- 第一个样本的 1 个 sigma 的填充区域
- 第一个样本的轮廓线
- 第二个样本的 2 sigma 的填充区域
- 第二个样本的 1 sigma 的填充区域
- 第二个样本的轮廓线
原来所有的填充区域都有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
在 python3 中,我在使用工具 GetDist
tool to produce triplot of covariance matrix.
1) 目前,我只需调用一次绘图函数 (triangle_plot) 就可以在同一张图上绘制 2 个协方差矩阵。将要绘制的协方差矩阵列表指定为第一个输入足以让每个矩阵具有 (1 sigma,2 sigma) 等高线。这里是一个由 2 个协方差矩阵生成的三重图示例(填充区域对应于 1 sigma 置信水平 (68%),阴影对应于 2 sigma C.L (95%))。颜色标识每个矩阵(此处为红色和蓝色):
我的主要目标是我想像这样按降序优先重叠:
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 西格玛红色圆盘不要被 2 西格玛蓝色阴影隐藏。
这是我想要的示例(注意,与上面的三联图相比,红色和蓝色之间存在反转):
不要在意黄色轮廓。如您所见,1 sigma 蓝色磁盘优先于 2 红色阴影 sigma 磁盘。这与我想要的行为完全相同。
在上面的三图中,我尝试了很多 alpha 参数,但由于颜色混合且不再与图例(红色和蓝色)对应,因此一团糟。
2) 鉴于我没有在 GetDist
的源代码中找到更改此优先级的事实,我尝试调用两次函数 triangle_plot
每次调用一个矩阵。
但不幸的是,2次调用后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
函数以重叠第一个三联图和第二个三联图(蓝色)?
事实上,这将允许我使用置信度标识符(C.L:68% 或 95%),然后解决这个优先级问题。
不幸的是,当我调用 2 次 triangle_plot 函数时,重叠不起作用:只保留最后一次调用,第一次调用似乎已从图中删除。
在这种三联图中强制重叠的方法是什么(重叠等高线但不重叠标签和刻度)?我们可以先验地认为这很简单,因为三联图只是 boxes/subplots) 但我不能仅仅设法执行这种重叠。我试图在两个调用之间插入:
plt.show(block=False) # do not block
但这不起作用。我认为这是因为我在最后将图形保存在文件中:
# Save figure
g.fig.savefig('Comparison_Overlap.pdf')
更新 1
感谢 Stef。最后一个问题:水平和垂直 xticks 被轮廓和填充区域隐藏,我不知道后者是 zorder
哪个。这里有 2 个例子说明了这个问题:
可以看到0.95对应的xtick被mask了
可以看到右下角的xtick也被屏蔽了
更新 2
@Stef
的解决方案完美运行,但仍然存在一个小问题:xticks 和 yticks 被轮廓隐藏了。
默认情况下,xticks 的 z-order
of 由 :
g.fig.axes[0].xaxis.get_major_ticks()[0].zorder
那个 returns : 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
这样,我可以让轮廓不被轮廓隐藏。例如,如下所示:
这个解决方案不是很容易,因为我必须处理负值 ([-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
:我不明白这种行为:
可能出了什么问题?
更新 3
这是我试图解决关于我想要的刻度优先级问题的最后一件事,即让 xticks/yticks 出现在轮廓前面,而不是即时出现的相反部分。
如果我默认打印 get_major_ticks()
和 get_ticklines()[0])
的值 zorder
,我得到:
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)
但我无法修改 zorder1
(默认等于 0
)。
如何更改 zorder1
的 0
值(引用 get_ticklines()
)?
这有点老套,但您可以稍后更改轮廓的 zorder
。为此,我们采用下三角图并设置路径和线集合的 zorder
属性。它们按以下顺序出现:
- 第一个样本的 2 sigma 的填充区域
- 第一个样本的 1 个 sigma 的填充区域
- 第一个样本的轮廓线
- 第二个样本的 2 sigma 的填充区域
- 第二个样本的 1 sigma 的填充区域
- 第二个样本的轮廓线
原来所有的填充区域都有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