pythonmatplotlibtextcolorbar

How to align text with the edge of the rightmost element in a matplotlib figure?


The following code aligns some text to the right edge of the color bar:

import matplotlib.pyplot as plt
import numpy as np

data = np.random.rand(10, 10)
img = plt.imshow(data, cmap='viridis')
color_bar = plt.colorbar(img, orientation='vertical')

color_bar.set_label('Color Bar Label', rotation=270, labelpad=15)

color_bar_position = color_bar.ax.get_position()

color_bar_width = color_bar_position.width

plt.text(color_bar_position.x1 + color_bar_width,1.02,'Right-Aligned Text', ha='right', va='center', transform=color_bar.ax.transAxes)

plt.show()

How can I edit this so the text is aligned with the right edge of the color bar label (denoted by the red line) - i.e. the right edge of the rightmost element in the figure below? This figure is just an example; I need to apply this to a much more complex piece of code, so I need to be able to extract the x-direction figure coordinate of this edge to specify the text position.

enter image description here


Solution

  • If you use annotate instead of text then you can specify the x- and y- positions relative to different artists or axes, or various axes/figure coordinates. Note that axis label positions are not known until the figure is drawn (see my answer to this other question) so here I force a draw with draw_without_rendering in order to line up the annotation with the label:

    import matplotlib.pyplot as plt
    import numpy as np
    
    data = np.random.rand(10, 10)
    img = plt.imshow(data, cmap='viridis')
    color_bar = plt.colorbar(img, orientation='vertical')
    
    color_bar.set_label('Color Bar Label', rotation=270, labelpad=15)
    color_bar_label = color_bar.ax.yaxis.label
    
    plt.gcf().draw_without_rendering()
    
    plt.annotate('Right-Aligned Text', (1, 1.02),
                 xycoords=(color_bar_label, color_bar.ax),
                 ha='right', va='center')
    
    plt.show()
    

    If you want to line the text up with the rightmost artist without knowing a priori what that artist is, you could find the extent of all combined artists with get_tight_bbox.

    import matplotlib.pyplot as plt
    import numpy as np
    
    data = np.random.rand(10, 10)
    img = plt.imshow(data, cmap='viridis')
    color_bar = plt.colorbar(img, orientation='vertical')
    
    color_bar.set_label('Color Bar Label', rotation=270, labelpad=15)
    
    fig_bbox = plt.gcf().get_tightbbox()
    rightmost = fig_bbox.max[0] * 72  # Convert position in inches to points
    
    plt.annotate('Right-Aligned Text', (rightmost, 1.02),
                 xycoords=('figure points', color_bar.ax),
                 ha='right', va='center')
    
    plt.show()
    

    enter image description here