I've been trying to make my annotations avoid the plot area and get drawn completely outside, using AdjustText so they don't overlap. I haven't found any solution or hidden parameter in the matplotlib or AdjustText docs so far to do this. What am I missing? All I found were ways to clip the annotations
import matplotlib.pyplot as plt
from matplotlib.widgets import CheckButtons
from adjustText import adjust_text
x_axis1 = [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 5.5, 6.0, 10.5, 15.0, 15.5]
y_axis1 = [60.0, 80.0, 70.0, 60.0, 70.0, 50.0, 80.0, 100.0, 80.0, 60.0, 50.0]
x_axis2 = [0.0, 0.3, 0.6, 0.9]
y_axis2_labels = ['First Station', 'Second Station', 'Third Station', 'Last station']
max_y = max(y_axis1)
fig, ax = plt.subplots()
ax.set_xlabel("Distance [km]")
ax.set_ylabel("Speed [km/h]")
l0, = ax.step(x_axis1, y_axis1, label="Speed", where="post")
ax2 = ax.twiny()
ax2.set_xlim(ax.get_xlim())
ax2.set_label('Stations')
plt.xticks([])
ax2.tick_params(
axis="x",
which='major',
direction="in",
width=1.5,
length=7,
labelsize=10,
color="red",
)
for x in x_axis2:
ax2.axvline(x, color='red', ls=':', lw=1.5)
# -------------------
y_axis2 = [max(ax.get_ylim()) for i in range(len(x_axis2))]
texts = [
plt.text(
x_axis2[i],
y_axis2[i],
y_axis2_labels[i],
ha='center',
va='center',
# annotation_clip=False,
rotation=20,
clip_on=False
) for i in range(len(x_axis2))
]
adjust_text(
texts,
[ax.get_xlim()],
[ax.get_ylim()],
arrowprops=dict(
arrowstyle='->',
connectionstyle="arc,angleA=-90,angleB=0,armA=30,armB=30,rad=5",
color='red'
),
)
# -------------------
lines = [l0, ax2]
rax = plt.axes([0, 0, 0.12, 0.1])
labels = [str(line.get_label()) for line in lines]
visibility = [line.get_visible() for line in lines]
check = CheckButtons(rax, labels, visibility)
def func(label):
index = labels.index(label)
lines[index].set_visible(not lines[index].get_visible())
plt.draw()
check.on_clicked(func)
fig.tight_layout()
plt.show()
This is the current output I get: