下面的代码生成一个简单的绘图,其中顶部和右侧脊柱被隐藏,并且左侧和底部脊柱分别沿 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可以看出,我不能只将一个函数传递给书脊来不断评估是否应该显示书脊。
我所期待的:
如果脊柱超出轴限制,则能够隐藏它们。
这是一个可能的解决方案。它涉及一些技巧来保持网格线,同时使刻度线(几乎)不可见。
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()