Repository: matplotlib/matplotlib
File: galleries/examples/text_labels_and_annotations/demo_annotation_box.py (Python)

Code before:
# Annotate the 1st position with a text box ('Test 1')
offsetbox = TextArea("Test 1")

ab1 = AnnotationBbox(offsetbox, xy,
                     xybox=(-20, 40),
                     xycoords='data',
                     boxcoords="offset points",
                     arrowprops=dict(arrowstyle="->"),
                     bboxprops=dict(boxstyle="sawtooth"))
ax.add_artist(ab1)

# Annotate the 1st position with another text box ('Test')
offsetbox = TextArea("Test 2")

ab2 = AnnotationBbox(offsetbox, (1, .85),
                     xybox=(.75, xy[1]),
                     xycoords=ab1,
                     boxcoords=("axes fraction", "data"),
                     box_alignment=(0., 0.5),
                     arrowprops=dict(arrowstyle="->"))
ax.add_artist(ab2)

# %%%%
# Images
# ======
# The `.OffsetImage` container supports plotting images using `.BboxImage`

fig, ax = plt.subplots()
# Define a position to annotate (don't display with a marker)
xy = [0.3, 0.55]

# Annotate a position with an image generated from an array of pixels
arr = np.arange(100).reshape((10, 10))
im = OffsetImage(arr, zoom=2, cmap='viridis')
im.image.axes = ax

ab = AnnotationBbox(im, xy,
                    xybox=(-50., 50.),
                    xycoords='data',
                    boxcoords="offset points",
                    pad=0.3,
                    arrowprops=dict(arrowstyle="->"))
ax.add_artist(ab)

# Annotate the position with another image (a Grace Hopper portrait)
with get_sample_data("grace_hopper.jpg") as file:
    arr_img = plt.imread(file)

imagebox = OffsetImage(arr_img, zoom=0.2)
imagebox.image.axes = ax


Review comment (suggestion):
Mentioning `.BboxImage` does not add value here. It's not used in the code and I assume most users don't know it either.

I suggest to leave this out. Possibly the better place for that information is the `.OffsetImage` docstring.

Code after:

fig, axd = plt.subplot_mosaic([['t1', '.', 't2']], layout='compressed')

# Define a 1st position to annotate (display it with a marker)
xy1 = (.25, .75)
xy2 = (.75, .25)
axd['t1'].plot(*xy1, ".r")
axd['t2'].plot(*xy2, ".r")
axd['t1'].set(xlim=(0, 1), ylim=(0, 1), aspect='equal')
axd['t2'].set(xlim=(0, 1), ylim=(0, 1), aspect='equal')

# Draw a connection patch arrow between the points
c = ConnectionPatch(xyA=xy1, xyB=xy2,
                    coordsA=axd['t1'].transData, coordsB=axd['t2'].transData,
                    arrowstyle='->')
fig.add_artist(c)

# Annotate the ConnectionPatch position ('Test 1')
offsetbox = TextArea("Test 1")

# place the annotation above the midpoint of c
ab1 = AnnotationBbox(offsetbox,
                     xy=(.5, .5),
                     xybox=(0, 30),
                     xycoords=c,
                     boxcoords="offset points",
                     arrowprops=dict(arrowstyle="->"),
                     bboxprops=dict(boxstyle="sawtooth"))
fig.add_artist(ab1)

# %%%%
# Images
# ======
# The `.OffsetImage` container facilitates using images as annotations

fig, ax = plt.subplots()
# Define a position to annotate
xy = (0.3, 0.55)
ax.scatter(*xy, s=200, marker='X')

# Annotate a position with an image generated from an array of pixels
arr = np.arange(100).reshape((10, 10))
im = OffsetImage(arr, zoom=2, cmap='viridis')
im.image.axes = ax

# place the image NW of xy
ab = AnnotationBbox(im, xy=xy,
                    xybox=(-50., 50.),
                    xycoords='data',
                    boxcoords="offset points",
                    pad=0.3,