如何将“零”matplotlib 脊椎剪裁到轴限制之外?

问题描述 投票:0回答:1

下面的代码生成一个简单的绘图,其中顶部和右侧脊柱被隐藏,并且左侧和底部脊柱分别沿 y 轴和 x 轴设置。如果我在图中平移,那么左侧和底部的脊柱仍然可见,即使它们位于

ax.get_xlim()
ax.get_ylim()
指定的坐标之外,我不希望发生这种情况。本质上,我希望在平移时连续评估像
adjust_spines(ax)
这样的东西,而不必设置
fig.subplots_adjust(left=0, bottom=0, right=1, top=1)
。这可能吗?

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
fig.subplots_adjust(left=0.2, bottom=0.2, right=0.9, top=0.8)

ax.spines[['right', 'top']].set_visible(False)
ax.grid(linestyle='--')

ax.spines['left'].set_position('zero')
ax.spines['bottom'].set_position('zero')

x = np.linspace(-3, 5)
ax.plot(x, x/2)

# The left spine is not clipping correctly in the x-direction,
# and the bottom spine is not clipping correctly in the y-direction.
ax.spines['left'].set(clip_on=True)
ax.spines['bottom'].set(clip_on=True)


# Should happen continuously:
def adjust_spines(axis):
    x_min, x_max = axis.get_xlim()
    y_min, y_max = axis.get_ylim()
    axis.spines['left'].set_visible(x_min <= 0 <= x_max)
    axis.spines['bottom'].set_visible(y_min <= 0 <= y_max)


plt.show()

代码运行后我立即看到的内容:

向左下角平移后看到的内容(注意白色空白):

我尝试过的: 我尝试过直接修改脊椎的剪切属性,如代码所示,但这不起作用。我还尝试将脊柱

clip_box
设置为等于
ax.get_position()
Bbox,但这也不起作用。据我从阅读书脊文档matplotlib spins可以看出,我不能只将一个函数传递给书脊来不断评估是否应该显示书脊。 我所期待的: 如果脊柱超出轴限制,则能够隐藏它们。

python matplotlib axis
1个回答
0
投票

这是一个可能的解决方案。它涉及一些技巧来保持网格线,同时使刻度线(几乎)不可见。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter, ScalarFormatter

eps = 1.e-10

fig, ax = plt.subplots()

ax.spines[['right', 'top']].set_visible(False)
ax.grid(linestyle='--')

ax.spines['left'].set_position('zero')
ax.spines['bottom'].set_position('zero')

x = np.linspace(-3, 5)
ax.plot(x, x/2)


xticklen = ax.xaxis.majorTicks[0].tick1line.get_markersize()
yticklen = ax.yaxis.majorTicks[0].tick1line.get_markersize()


def adjust_x(axis):
    y_min, y_max = axis.get_ylim()
    if not y_min <= 0 <= y_max:
        axis.spines['bottom'].set_visible(False)
        axis.xaxis.set_tick_params(length=eps)
        axis.xaxis.set_major_formatter(NullFormatter())
    else:
        axis.spines['bottom'].set_visible(True)
        axis.xaxis.set_tick_params(length=xticklen)
        axis.xaxis.set_major_formatter(ScalarFormatter())


def adjust_y(axis):
    x_min, x_max = axis.get_xlim()
    if not x_min <= 0 <= x_max:
        axis.spines['left'].set_visible(False)
        axis.yaxis.set_tick_params(length=eps)
        axis.yaxis.set_major_formatter(NullFormatter())
    else:
        axis.spines['left'].set_visible(True)
        axis.yaxis.set_tick_params(length=yticklen)
        axis.yaxis.set_major_formatter(ScalarFormatter())


cb_registry = ax.callbacks

cid1 = cb_registry.connect('xlim_changed', adjust_y)
cid2 = cb_registry.connect('ylim_changed', adjust_x)

fig.show()
© www.soinside.com 2019 - 2024. All rights reserved.