Home > Blockchain >  How to gain control over annotate arrows
How to gain control over annotate arrows

Time:05-10

I'm trying to insert arrows (brackets) in plots using the annotate package, but I cannot figure out what the input parameters mean. I read the documentation and I'm still unsure of how to control the arrows. Here's an example starting point:

import matplotlib.pyplot as pl
import numpy as np

fig = pl.figure(figsize=(3.25, 2.5))
ax0 = fig.add_subplot(111)

x, y = np.arange(10), np.arange(10) * -1

for offset in range(5):
    ax0.plot(x   offset, y, lw=1)


# add annotation arrow
bbox = dict(facecolor="w",
            alpha=0.95,
            ls="None",
            boxstyle="round",
            pad=0.1)

ax0.annotate(text="Example",
             xy=(7.5, -5),
             xytext=(0, -9),
             arrowprops=dict(arrowstyle="-[",
                             linewidth=1,
                             connectionstyle="arc,armA=90,angleA=0,angleB=-40,armB=85,rad=0"),
             verticalalignment="bottom",
             horizontalalignment="left",
             fontsize=8,
             bbox=bbox)

fig.show()

I want the bracket to span the width of all of the drawn lines (as if to say "these" lines are what the annotation refers to), but I cannot figure out how to change the bracket width.

Another issue is interpreting armA and armB (the arrow lines currently look ugly). I understand these refer to the length of line segments, but I cannot figure out what the units are (pixels?), much less how to automate generating their lengths.

Can you please provide guidance on how to adjust the width of the bracket and what the connectionstyle parameters mean? If this is documented somewhere I would appreciate the reference (even if it comes with a RTFM-type comment).

CodePudding user response:

I think the parameter you want is mutation_scale.

I changed your annotate command to this and I think it looks reasonable now, but it took some manual adjustment. If you had a consistent pattern in multiple figures you could probably calculate the angles and lengths that you want and use them as inputs, but for your example this seems to work reasonably well.

ax0.annotate(text="Example",
             xy=(8.5, -6.5),
             xytext=(0, -9),
             arrowprops=dict(arrowstyle="-[",
                             linewidth=1,
                             mutation_scale=22,    
             connectionstyle="arc,armA=70, \
                              angleA=0, \
                              angleB=-45, \
                              armB=50, \
                              rad=0"), \
                 verticalalignment="bottom",
                 horizontalalignment="left",
                 fontsize=8,
                 bbox=bbox)
  • Related