1

I would like to draw/plot a "bracket" (to keep it simple, it is a sequence of points that forms an arc) as shown in red in the first picture.

The figure where I want the bracket

I created the bracket in another figure, but I do not know how to include/draw/plot it in the first figure. Here is the bracket, that would be transformed as needed to fit the space between the small labels and the group Labels.

The bracket

Here is the MWE:

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(8, 1, figsize=(8,9), sharex=True)
for i, ax in enumerate(axs.flat):
    ax.plot([1,2])
    ax.set_ylabel('Label ' + str(i))
axs[7].set_xlabel('The common x Label')

plt.annotate('Group Label (0,1,2,3)', xy=(.02, 0.7), rotation=90, xycoords='figure fraction',
            horizontalalignment='center', verticalalignment='center', fontsize=14, color='k')
plt.annotate('Group Label (4,5,6,7)', xy=(.02, 0.3), rotation=90, xycoords='figure fraction',
            horizontalalignment='center', verticalalignment='center', fontsize=14, color='k')

# Plot a 'bracket'
plt.figure()
npoints = 100
td = np.linspace(np.pi*3/4, np.pi*5/4, npoints)
xd = np.cos(td)
yd = np.sin(td)
plt.plot(xd,yd)

Edit: I believe using a PathPatch would be the best solution, like in this Matplotlib example. I just don't know how to do it.

Pedro
  • 330
  • 2
  • 12
  • Maybe something like this [answer](https://stackoverflow.com/a/62388611/7758804). Seems like it might be better to only have two subplots and plot four groups in each subplot with the lines differentiated by legend / color. – Trenton McKinney Oct 25 '21 at 13:50
  • 1
    I am pretty sure using a "patch" might be an effective solution, just do not know how to do it. – Pedro Oct 26 '21 at 09:36
  • @paul-brodersen Can you give a helping hand figuring out the solution with patches? – Pedro Oct 29 '21 at 11:05

1 Answers1

1

You can achieve that by using plt.GridSpec and by masking the axis of your bracket by using plt.box(False) and plt.xticks([]) and plt.yticks([]). The arc of the bracket can also be changed by changing the size of the subplot. Here is what the code looks like:

import matplotlib.pyplot as plt
import numpy as np

fig= plt.figure(figsize=(10,10))

gs=plt.GridSpec(16,5)
for k in range(8):
  plt.subplot(gs[2*k:2*k+2,1:5])
  plt.plot([1,2],[1,2])
  plt.ylabel('Label ' + str(k))
  if k==7:
    plt.xlabel('The common x Label')


plt.subplot(gs[0:8,0:1])
npoints = 100
td = np.linspace(np.pi*3/4, np.pi*5/4, npoints)
xd = np.cos(td)
yd = np.sin(td)
plt.plot(xd,yd)
plt.box(False)
plt.xticks([])
plt.yticks([])

plt.subplot(gs[8:16,0:1])
plt.plot(xd,yd)
plt.box(False)
plt.xticks([])
plt.yticks([])
plt.tight_layout()



plt.annotate('Group Label (0,1,2,3)', xy=(.015, 0.75), rotation=90, xycoords='figure fraction',
            horizontalalignment='center', verticalalignment='center', fontsize=14, color='k')
plt.annotate('Group Label (4,5,6,7)', xy=(.015, 0.3), rotation=90, xycoords='figure fraction',
            horizontalalignment='center', verticalalignment='center', fontsize=14, color='k')

and the output gives:

enter image description here

jylls
  • 4,395
  • 2
  • 10
  • 21
  • That is a workaround, for sure. But in the way, "The common x Label" is not common to x labels anymore... – Pedro Oct 26 '21 at 09:33
  • If you would like to remove the ticks on the x axis for the first 7 subplots, you can add `plt.xticks([])` in the first 7 iterations only of the `for` loop. The output will then be pretty much like yours. – jylls Oct 26 '21 at 13:59
  • It is more about the behavior than the aesthetics. In my MWE, they all share the same x, meaning that, for example, when you zoom in on one axe, all other will also zoom in. – Pedro Oct 26 '21 at 14:10