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

时间:2018-03-09 14:10:07

标签: python matplotlib gridlines

我想在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本身的所有兄弟轴。然而,这几乎可以工作,左轴网格("原始"轴)关闭但不是右轴网格。我发现get_shared_x_axes()的文档非常无用,我甚至不理解返回的内容。

编辑2:

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

1 个答案:

答案 0 :(得分:1)

无法确切知道一组共享轴的哪个轴是通过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()

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

按顺序查找twinx轴

似乎在通过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)

然而,我没有找到任何理由这样的情况,因此它只是一个假设,在某些情况下可能证明是错误的。

按属性查找twinx

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

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)