annotate problem when drawing arrows with segments out of axis

I use annotate() to draw arrows around, but there is two problems when the extremities lies outside of the axis’ limits:

  1. If the start of the arrow is outside, the arrow drawing is not stopped at the axes.
  2. If the arrow head is outside, then the arrow is not drawn at all.

Here’s a small snippet showing the problem:

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt

fig1 = plt.figure()

ax1 = fig1.add_subplot(221)
ax2 = fig1.add_subplot(222)
ax3 = fig1.add_subplot(223)
ax4 = fig1.add_subplot(224)
axes = [ax1, ax2, ax3, ax4]

r0 = [0.5, 0.0]
r1 = [0.5, 1.0]

ylims = [( 0.0,  1.0),
         (-0.5,  1.5),
         ( 0.5,  1.5),
         (-0.5,  0.5)]

for i in xrange(len(axes)):
    ax = axes[i]
    ax.annotate('', xy     = (r1[0], r1[1]), xycoords='data',
                    xytext = (r0[0], r0[1]), textcoords='data',
                    arrowprops=dict(arrowstyle="-|>") )
    ax.set_xlim(( 0.0,  1.0))
    ax.set_ylim(ylims[i])
    ax.text(0.6, 0.5, str(ylims[i]), transform=ax.transAxes)

plt.show()

Author: Fantashit

1 thought on “annotate problem when drawing arrows with segments out of axis

  1. The primary purpose of “annotate” is to annotate something with text and optionally with an arrow. And the current behavior is a feature that makes sense in most cases. For what you want, you need to adjust two things. First you should suppress the current behavior of annotation, and you can do this by setting “annotation_clip=False” (see the documentation for more details). You further need to clip the arrow with bbox of the axes. So, you need something like below.

        ann = ax.annotate('', xy     = (r1[0], r1[1]), xycoords='data',
                          xytext = (r0[0], r0[1]), textcoords='data',
                          arrowprops=dict(arrowstyle="-|>"),
                          annotation_clip=False)
        ann.arrow_patch.set_clip_box(ax.bbox)

Comments are closed.