Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw a separator or lines between subplots

I have plot four subplots in one figure and they shares xaxis with each other.

However, there is no separator between those subplots. I want to draw a line between each of them. or is there any separator could be adopted in those subplots?

At least there should be separator between the subplots' axis. I think it should be looked as below figure.

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

  subplot1

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

  subplot2

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

  ...

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

like image 316
Readon Shaw Avatar asked Sep 28 '14 11:09

Readon Shaw


People also ask

How do you add a gap between subplots?

We can use the plt. subplots_adjust() method to change the space between Matplotlib subplots. The parameters wspace and hspace specify the space reserved between Matplotlib subplots. They are the fractions of axis width and height, respectively.


1 Answers

If the axes/subplots have decorators like x labels or tick labels, it's not straight forward to find the correct position of the lines that should separate the subplots, such that they do not overlap with the texts.

One solution to this can be to get the extent of the axes including decorators and take the mean in between the bottom of the upper and the top of the lower extent.

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()

enter image description here

like image 197
ImportanceOfBeingErnest Avatar answered Sep 17 '22 13:09

ImportanceOfBeingErnest