Wald
Wald

Reputation: 311

Aligning annotated text with colorbar label text

I'd like to find a way to make an annotation that automatically aligns with the label text of a colorbar. Take this example:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(figsize=(5,10))
data = np.arange(1000, 0, -10).reshape(10, 10)
im = ax.imshow(data, cmap='Blues')
clb = plt.colorbar(im, shrink=0.4)
clb.ax.annotate('text', xy=(1, -0.075), xycoords='axes fraction')

enter image description here

I want to have the last t of "text" to be on the same x coordinate as the last 0 of 1000 in the colorbar label. I can do so manually by adjusting the xy parameter in annotate, but I have to do this for many graphs and would like to find a way to get the parameter from somewhere automatically.

How can I get the maximum x coordinate of the text labes and annotate in a way where the annotation ends on that coordinate? Could someone point me in the right direction? Thanks a lot!

Upvotes: 1

Views: 820

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339350

Since the labels are left-aligned, but you want to align your additional text according to the end of that label, I fear there is no other choice than to find out the coordinates from the drawn figure and place the label accordingly.

import matplotlib.pyplot as plt
from matplotlib import transforms
import numpy as np

fig, ax = plt.subplots(figsize=(5,4))
data = np.arange(1000, 0, -10).reshape(10, 10)
im = ax.imshow(data, cmap='Blues')
cbar = plt.colorbar(im)


# draw figure first to be able to retrieve coordinates
fig.canvas.draw()
# get the bounding box of the last label
bbox = cbar.ax.get_yticklabels()[-1].get_window_extent()
# calculate pixels back to axes coords
labx,_ = cbar.ax.transAxes.inverted().transform([bbox.x1,0]) 
ax.annotate('text', xy=(labx, -0.075), xycoords=cbar.ax.transAxes,
                 ha = "right")

plt.show()

enter image description here

Note that this approach will fail once you change the figure size afterwards or change the layout in any other way. It should hence always come last in your code.

Upvotes: 1

Related Questions