在子图之间绘制分隔线或线条

Rea*_*haw 6 python matplotlib

我在一个图中绘制了四个子图,并且它们彼此共享xaxis。

但是,这些子图之间没有分隔符。我想在它们之间画一条线。还是在这些子图中可以使用任何分隔符?

子图的轴之间至少应有分隔符。我认为应该如下图所示。

\ ------------------------------------

  subplot1
Run Code Online (Sandbox Code Playgroud)

\ ------------------------------------

  subplot2
Run Code Online (Sandbox Code Playgroud)

\ ------------------------------------

  ...
Run Code Online (Sandbox Code Playgroud)

\ ------------------------------------

Imp*_*est 13

如果轴/子图有像 x 标签或刻度标签这样的装饰器,那么找到应该分隔子图的线的正确位置并不容易,这样它们就不会与文本重叠。

对此的一种解决方案是获取包括装饰器在内的轴的范围,并在上部范围的底部和下部范围的顶部之间取平均值。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.transforms as mtrans

fig, axes = plt.subplots(3,2, squeeze=False)

for i, ax in enumerate(axes.flat):
    ax.plot([1,2])
    ax.set_title('Title ' + str(i+1))
    ax.set_xlabel('xaxis')
    ax.set_ylabel('yaxis')

# rearange the axes for no overlap
fig.tight_layout()

# Get the bounding boxes of the axes including text decorations
r = fig.canvas.get_renderer()
get_bbox = lambda ax: ax.get_tightbbox(r).transformed(fig.transFigure.inverted())
bboxes = np.array(list(map(get_bbox, axes.flat)), mtrans.Bbox).reshape(axes.shape)

#Get the minimum and maximum extent, get the coordinate half-way between those
ymax = np.array(list(map(lambda b: b.y1, bboxes.flat))).reshape(axes.shape).max(axis=1)
ymin = np.array(list(map(lambda b: b.y0, bboxes.flat))).reshape(axes.shape).min(axis=1)
ys = np.c_[ymax[1:], ymin[:-1]].mean(axis=1)

# Draw a horizontal lines at those coordinates
for y in ys:
    line = plt.Line2D([0,1],[y,y], transform=fig.transFigure, color="black")
    fig.add_artist(line)


plt.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


Rea*_*haw 6

我找到了一个解决方案,但不是一个完美的解决方案,但对我有用。

将以下代码应用于子图的每个对象。

其中 [-1, 1.5] 是假设覆盖图中 X 轴所有区域的值。不完全一样。

axes.plot([-1, 1.5], [0, 0], color='black', lw=1, transform=axes.transAxes, clip_on=False)
axes.plot([-1, 1.5], [1, 1], color='black', lw=1, transform=axes.transAxes, clip_on=False)
Run Code Online (Sandbox Code Playgroud)

我尝试了另一种我认为最完美的方法。正如下面的代码所示。

    trans = blended_transform_factory(self.figure.transFigure, axes.transAxes)
    line = Line2D([0, 1], [0, 0], color='w', transform=trans)
    self.figure.lines.append(line)
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,该行将从每个图形边缘的开始处开始,并且会随着图形大小的变化而变化。