I want to display vertical brackets to group ylabels on the left side of a plot, to group for instance the first 3 variables together, then the following two.
By carefully tuning the position of xy and xytest of annotate using fancyarrow I can manage to get somehow vertical brackets using annotate and fancyarrows but placing them without breaking the alignment is such a hassle that it's near undoable. This is because the process is at the same time extremely painful and brittle because one cannot just place xy and xytest at the same horizontal, because the angle depends on the text size and the length of the bracket. Plus with the rotation it's hard to manage the direction of the bracket on my example it's reversed for some reasons.
Here is my very poor unsuccessful trial:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
from matplotlib.pyplot import figure
figure(figsize=(10, 5), dpi=50)
np.random.seed(42)
df = pd.DataFrame({f"var{i}": np.random.uniform(-1., 1., 2) for i in range(10)})
df["facet"] = [0, 1]
# Vertical plot
df = df.melt('facet', var_name='Variable', value_name='values')
ax = sns.barplot(data=df, x="values", y="Variable")
ylims = ax.get_ylim()
xlims = ax.get_xlim()
xmin = min(xlims)
xmax = max(xlims)
ymin = min(ylims)
ymax = max(ylims)
ax.annotate('Group1 vertical', xytext=(1.4 * xmin, ymax / 2), xy=(1.2 * xmin, ymax / 2 - (ymax - ymin)/7.5),
fontsize=10, ha='center', va='bottom',
bbox=dict(boxstyle='square', fc='white'),
arrowprops=dict(arrowstyle=f'-[, widthB=10, lengthB={0.5 * xmin}', lw=2.0), rotation=90, clip_on=False, annotation_clip=False)
ax.annotate('Group2 vertical', xytext=(1.4 * xmin, ymax * 4 / 5), xy=(1.2 * xmin, ymax * 4 / 5 - (ymax - ymin)/7.5),
fontsize=10, ha='center', va='bottom',
bbox=dict(boxstyle='square', fc='white'),
arrowprops=dict(arrowstyle=f'-[, widthB=5, lengthB={0.5 * xmin}', lw=2.0), rotation=90, clip_on=False, annotation_clip=False)
ax.yaxis.label.set_visible(False)
ax.xaxis.label.set_visible(False)
plt.tight_layout()
plt.show()
Can it be done and done somehow elegantly once you have placed xy or xytest for instance and fixed the length and width of the bracket ?
