【问题标题】:Remove only overlapping ticks in subplots grid仅删除子图网格中的重叠刻度
【发布时间】:2016-10-24 12:45:11
【问题描述】:

我创建了一个子图网格,子图之间没有任何空格,共享 x,y 轴。我只显示外部子图的刻度和标签。问题是刻度数在子图的边界处重叠。使用 MaxNLocator,我可以删除上刻度或下刻度,但只能同时删除所有图。

问题:我怎样才能只为某些地块保留最高刻度(在这种情况下,x=2.0 仅在右下角的子图中,y=3 仅在左上角的子图中)?为什么我对某些子图的刻度条件设置失败?

代码:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator

numPlotsY = 3
numPlotsX = 3
f, ax_grid = plt.subplots(numPlotsY,numPlotsX,sharex=True,sharey=True)

A = np.arange(numPlotsY)+1.0
phi = np.arange(numPlotsX)
x = np.linspace(0,2.0,100)
fontsize = 18

for y_i in range(0,numPlotsY):
    for x_i in range(0,numPlotsX):
        y = A[y_i]*np.sin(x*np.pi + phi[x_i])
        ax = ax_grid[y_i,x_i]
        ax.plot(x,y,lw=2.0)

        if x_i == 0:
            ax.set_ylabel(r'$y$', fontsize=fontsize)

        if y_i == numPlotsY-1:
            ###########################
            # Why doesn't this work?! #
            ###########################
            if x_i != numPlotsX-1:
                nbins = len(ax.get_xticklabels())
                ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='upper'))
            else:
                nbins = len(ax.get_xticklabels())
                ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune=None))
            ax.set_xlabel(r'$x/\pi$', fontsize=fontsize)

        if y_i == 0:
            ax.set_title(r'$\phi=%s$' % phi[x_i], fontsize=fontsize)

        if x_i == numPlotsX-1:
            ax.annotate(r'$A=%d$' % A[x_i], xy=(1.1,0.5), rotation=90,
                        ha='center',va='center',xycoords='axes fraction', fontsize=fontsize)

f.subplots_adjust(wspace=0,hspace=0)
plt.suptitle(r'$A\cdot\sin\left(2\pi x + \phi\right)$',fontsize=18)
plt.show()

【问题讨论】:

  • This thread 说“由于轴是共享的,刻度标签也是共享的”,所以你所追求的可能是不可能的。请参阅密切相关的问答here

标签: python matplotlib


【解决方案1】:

正如@AndrasDeak 所指出的,只要我设置了 sharex=True,sharey=True,我就无法修改单个子图刻度。 解决方案是将它们设置为 false

f, ax_grid = plt.subplots(numPlotsY,numPlotsX,sharex=False,sharey=False)

并将我原来帖子中的条件语句更改为:

# If left-most column:  Remove all overlapping y-ticks
# Else:                 Remove all ticks
if x_i == 0:
    ax.set_ylabel(r'$y$', fontsize=fontsize)
    # If top left subplot:      Remove bottom y-tick
    # If bottom left subplot:   Remove top y-tick
    # Else:                     Remove top and bottom y-ticks
    if y_i == 0:
        nbins = len(ax.get_yticklabels())
        ax.yaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='lower'))
    elif y_i == numPlotsY-1:
        nbins = len(ax.get_yticklabels())
        ax.yaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='upper'))
    else:
        nbins = len(ax.get_yticklabels())
        ax.yaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='both'))
else:
    ax.yaxis.set_ticks([])

# If bottom row:    Remove all overlapping x-ticks
# Else:             Remove all ticks
if y_i == numPlotsY-1:
    # If bottom left subplot:   Remove right x-tick
    # If bottom right subplot:  Remove top left x-tick
    # Else:                     Remove left and right x-ticks
    if x_i == 0:
        nbins = len(ax.get_xticklabels())
        ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='upper'))
    elif x_i == numPlotsX-1:
        nbins = len(ax.get_xticklabels())
        ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='lower'))
    else:
        nbins = len(ax.get_xticklabels())
        ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='both'))
else:
    ax.xaxis.set_ticks([])

不是最优雅的结果,但它演示了如何仅操作重叠的刻度:

所有感兴趣的人的完整代码:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator

numPlotsY = 3
numPlotsX = 3
f, ax_grid = plt.subplots(numPlotsY,numPlotsX,sharex=False,sharey=False)

A = np.arange(numPlotsY)+1.0
phi = np.arange(numPlotsX)
x = np.linspace(0,2.0,100)
fontsize = 18

for y_i in range(0,numPlotsY):
    for x_i in range(0,numPlotsX):
        y = A[y_i]*np.sin(x*np.pi + phi[x_i])
        ax = ax_grid[y_i,x_i]
        ax.plot(x,y,lw=2.0)

        # If left-most column:  Remove all overlapping y-ticks
        # Else:                 Remove all ticks
        if x_i == 0:
            ax.set_ylabel(r'$y$', fontsize=fontsize)
            # If top left subplot:      Remove bottom y-tick
            # If bottom left subplot:   Remove top y-tick
            # Else:                     Remove top and bottom y-ticks
            if y_i == 0:
                nbins = len(ax.get_yticklabels())
                ax.yaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='lower'))
            elif y_i == numPlotsY-1:
                nbins = len(ax.get_yticklabels())
                ax.yaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='upper'))
            else:
                nbins = len(ax.get_yticklabels())
                ax.yaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='both'))
        else:
            ax.yaxis.set_ticks([])

        # If bottom row:    Remove all overlapping x-ticks
        # Else:             Remove all ticks
        if y_i == numPlotsY-1:
            # If bottom left subplot:   Remove right x-tick
            # If bottom right subplot:  Remove top left x-tick
            # Else:                     Remove left and right x-ticks
            if x_i == 0:
                nbins = len(ax.get_xticklabels())
                ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='upper'))
            elif x_i == numPlotsX-1:
                nbins = len(ax.get_xticklabels())
                ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='lower'))
            else:
                nbins = len(ax.get_xticklabels())
                ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='both'))
        else:
            ax.xaxis.set_ticks([])

        if y_i == 0:
            ax.set_title(r'$\phi=%s$' % phi[x_i], fontsize=fontsize)

        if x_i == numPlotsX-1:
            ax.annotate(r'$A=%d$' % A[x_i], xy=(1.1,0.5), rotation=90,
                        ha='center',va='center',xycoords='axes fraction', fontsize=fontsize)

f.subplots_adjust(wspace=0,hspace=0)
plt.suptitle(r'$A\cdot\sin\left(2\pi x + \phi\right)$',fontsize=18)
plt.show()

【讨论】:

  • 可能是一个愚蠢的问题,但为什么要摆脱所有的蜱虫,而你真正想要的是摆脱蜱虫标签?我的意思是,除了外面的,只要把formatter设置为nullformatter,不是吗?
  • @BUFU 好点。它主要是我想要(编辑)摆脱的刻度标签。蜱肯定会留下来。
【解决方案2】:

受 fromGiants 的回答启发,我得到了一个更清洁的解决方案。我使用plt.setp(ax.get_yticklabels()[0], visible=False) 将 yticklabels 设置为不可见。

def clear_overlapped_ticks(axs, axis='xy'):
    ny = len(axs)
    nx = len(axs[0])
    for y_i in range(0, ny):
        for x_i in range(0, nx):
            ax = axs[y_i][x_i]
            if 'y' in axis:
                if x_i == 0:
                    # If not bottom left subplot:   Remove bottom y-tick
                    if y_i < ny - 1:
                        print("here's the current ylabels:", ax.get_yticklabels())
                        plt.setp(ax.get_yticklabels()[0], visible=False)
                else:
                    ax.yaxis.set_ticklabels([])
                    ax.set_ylabel('')
            if 'x' in axis:
                if y_i == ny - 1:
                    # If not bottom left subplot:   Remove left x-tick
                    if x_i > 0:
                        print("here's the current xlabels:",
                              [i for i in ax.get_xticklabels()])
                        plt.setp(ax.get_xticklabels()[0], visible=False)
                else:
                    ax.xaxis.set_ticklabels([])
                    ax.set_xlabel('')

【讨论】:

    猜你喜欢
    • 2013-03-24
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 2015-08-02
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    相关资源
    最近更新 更多