3

I am plotting an arrow in matplotlib using annotate. I would like to make the arrow fatter. The effect I am after is a two-headed arrow with a thin edge line where I can control the arrow width i.e. not changing linewidth. I have tried kwargs such as width after this answer but this caused an error, I have also tried different variations of arrowstyle and connectorstyle again without luck. I'm sure it's a simple one!

My code so far is:

import matplotlib.pyplot as plt

plt.figure(figsize=(5, 5))
plt.annotate('', xy=(.2, .2),  xycoords='data',
            xytext=(.8, .8), textcoords='data',
            arrowprops=dict(arrowstyle='<|-|>',
                            facecolor='w',
                            edgecolor='k', lw=1))
plt.show()

I am using Python 2.7 and Matplotlib 1.5.1

Community
  • 1
  • 1
kungphil
  • 1,759
  • 2
  • 18
  • 27
  • So you want the actual line connecting the two arrowheads to become wider, not the actual arrowheads themselves? – DavidG Jul 21 '16 at 12:47
  • Yes, arrowheads (proportionally) as well but not the edge line (set with `edgecolor` whose width is defined with `lw`). Many thanks. – kungphil Jul 21 '16 at 12:52
  • I think I have the same problem, but no solution better than two simple arrows in opposite directions. This might be a clearer illustration of what you meant: https://stackoverflow.com/questions/64545470/how-to-remove-the-whitespace-between-the-tip-of-the-arrow-of-a-fancyarrowpatch-a/64545471#64545471 – Ciro Santilli OurBigBook.com Oct 26 '20 at 22:00

1 Answers1

1

The easiest way to do this will be by using FancyBboxPatch with the darrow (double arrow) option. The one tricky part of this method is that the arrow will not rotate around its tip but rather the edge of the rectangle defining the body of the arrow. I demonstrate that with a red dot placed at the rotation location.

import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib as mpl

fig = plt.figure()
ax = fig.add_subplot(111)

#Variables of the arrow
x0 = 20
y0 = 20
width = 20
height = 2
rotation = 45
facecol = 'cyan'
edgecol = 'black'
linewidth=5

# create arrow
arr = patches.FancyBboxPatch((x0,y0),width,height,boxstyle='darrow',
                             lw=linewidth,ec=edgecol,fc=facecol)

#Rotate the arrow. Note that it does not rotate about the tip
t2 = mpl.transforms.Affine2D().rotate_deg_around(x0,y0,rotation) + ax.transData


plt.plot(x0,y0,'ro') # We rotate around this point
arr.set_transform(t2) # Rotate the arrow


ax.add_patch(arr)

plt.xlim(10, 60)
plt.ylim(10, 60)

plt.grid(True)

plt.show()

Giving:

enter image description here

Ianhi
  • 2,864
  • 1
  • 25
  • 24