在 matplotlib 中找到所有共享的 x 轴并关闭兄弟姐妹上的网格

Find all shared x-axes in matplotlib and turn off the grid on siblings

我想在 pyQt/matplotlib 应用程序中找到所有共享的 x 轴兄弟 (ax_2 = ax_1.twinx()) 并关闭它们的网格。

我试着摆弄 ax.get_shared_x_axes().get_siblings(ax) 但这似乎太复杂了。我正在寻找类似于以下伪代码的解决方案

for ax in all_axes:
    if hasattr(ax,"is_sibling"):
        ax.grid(False)

编辑:

到目前为止我的摆弄是(大量借鉴http://matplotlib.1069221.n5.nabble.com/get-parent-or-child-from-twinx-or-twiny-td2038.html):

for ax in self.fig.axes:
    shared_x = [ax2 for ax2 in ax.get_shared_x_axes().get_siblings(ax) if ax2 is not ax]
    for ax2 in shared_x:
        ax2.grid(False)

列表理解应该找到 ax 的所有同级轴,而不是 ax 本身。这几乎可以工作,但是,左轴("original" 轴)的网格已关闭,但右轴的网格未关闭。我发现 get_shared_x_axes() 的文档非常无用,我什至不明白返回的内容。

编辑 2:

另一种可能更简单的方法是在右侧找到所有带有 y 标签的轴,但我不知道该怎么做。

无法确定一组共享轴中的哪些轴是通过 twinx 创建的。但是有办法接近它。

使用自定义属性

首先我要说的是,你当然可以自己创建属性来查询。

import matplotlib.pyplot as plt
plt.rcParams["axes.grid"] = True

fig, axes = plt.subplots(2,2)
ax5 = axes[0,1].twinx()
ax5.is_sibling = True
ax5.plot([2,4,3])
ax6 = axes[1,0].twinx()
ax6.plot([.1,.5,.6])
ax6.is_sibling = True


# later query the is_sibling attribute
for ax in fig.axes:
    if hasattr(ax,"is_sibling"):
        ax.grid(False)

plt.tight_layout()
plt.show()

这是迄今为止最干净的解决方案。

按顺序查找双轴

似乎在通过ax.get_shared_x_axes().get_siblings(ax)得到的轴列表中,原始轴总是在第二个位置。

 [twin axes, original axes, possible further shared axes]

因此您可以使用

for ax in fig.axes:
    shared_x = ax.get_shared_x_axes().get_siblings(ax)
    if len(shared_x) > 1:
        for a in [a for i,a in enumerate(shared_x) if i is not 1]:
            a.grid(False)

但是,我没有找到任何原因总是如此,因此这只是一个假设,在某些情况下可能会被证明是错误的。

按属性查找双胞胎

如果您要查找的轴是共享轴,其刻度在右侧并且与原始轴具有相同的位置,则可以查询这些属性。但是请注意,您也可以创建双轴,其标签位于左侧,因此这也取决于轴的创建方式。

def is_twinx(ax):
    s = ax.get_shared_x_axes().get_siblings(ax)
    if len(s) > 1:
        for ax1 in [ax1 for ax1 in s if ax1 is not ax]:
            if ax1.bbox.bounds == ax.bbox.bounds:
                if ax.yaxis.get_ticks_position() == "right":
                    return True
    return False

for ax in fig.axes:
    if is_twinx(ax):
        ax.grid(False)