I'm trying to automatically move matplotlib Text instances above some annotations which are not taken into account by plt.tight_layout or constrained_layout.
However, I can't seem to get the title positions to update using Text.set_position and redrawing afterwards (neither when using e.g. fig.canvas.draw() every update nor when calling title_text_instance.draw(renderer=fig.canvas.get_renderer())).
The text itself seems to update fine, and so does another annotation, which is weird as both title and annotation are Text objects.
Why doesn't the title position update in the code below?
Animation for illustration; the title text and annotation positions update as expected, but its position remains fixed:
Code:
#!/usr/bin/env/python3
import matplotlib.pyplot as plt
import matplotlib as mpl
N_FRAMES: int = 10
# Setting up the example.
mpl.use("TkAgg")
fig, ax = plt.subplots(figsize=(2, 1), dpi=300)
ax.plot(range(10), range(10))
t = ax.set_title("Example title", fontsize=6, alpha=.8, clip_on=False)
atext1 = '\n'.join(['Overlapping extra-axis annotation',
'above which I want to move the title',
'undetected by tight_layout or constrained_layout'])
atext2 = 'this annotation moves just fine...'
a1 = ax.annotate(atext1, xycoords='axes fraction', xy=(.25, 1),
rotation=10, clip_on=False, fontsize=3, color='r', alpha=.6)
a2 = ax.annotate(atext2, xycoords='axes fraction', xy=(.5, .5),
clip_on=False, fontsize=4, color='g')
fig.canvas.draw()
plt.tight_layout()
# ^^ Leaving out plt.tight_layout doesn't
# make a difference w.r.t position updates
for yoffset in range(N_FRAMES):
new_position = (t.get_position()[0], t.get_position()[1] - .5 + (yoffset / 2))
newpostext = '(' + ', '.join(f'{pos:.2f}' for pos in new_position) + ')'
# Changing positions
print(f'Set new position to', newpostext)
t.set_position(new_position) # Doesn't work
a2.set_position(new_position) # Works fine
t.set_text(f"Supposedly repositioned title position: \n (x, y) = {newpostext}")
plt.pause(.5)
plt.get_current_fig_manager().window.resizable(False, False)
plt.show(block=False)
plt.close(fig)
