How to get open and scaling arrow in matplotlib
In the watchdog by the sea I want to annotate the arrow column. Now that I can see how it might sound a little shrewd, I would love this arrow for both
- have an open head (i.e. not a closed triangle in the form of a head, but two open lines) and
- when the picture is resized.
I found two matplotlib methods for adding arrows ( arrow
and methods annotate
) but it seems they each lack one of these functions. This code appears side by side:
import seaborn as sns
sns.plt.subplot(121)
ax = sns.barplot(("x", "y", "z"), (1, 4, 7))
# head is not open
ax.arrow(0, 5, 0., -3.5, lw=1, fill=False,
head_length=.5, head_width=.2,
length_includes_head=True)
sns.plt.subplot(122)
ax = sns.barplot(("x", "y", "z"), (1, 4, 7))
# head does not scale with figure
ax.annotate("", xytext=(0, 5), xy=(0, 1.5),
arrowprops=dict(arrowstyle="->, head_length = 2, head_width = .5", lw=1))
sns.plt.show()
The left arrow is closed (ugly), but it scales fine when I resize the shape (because the size of the head is in data units, I suppose). The right arrow is nice and open, but it always keeps the same pixel size, regardless of the shape's size. So when the shape is small, the right arrow looks relatively large:
And when I make the shape bigger, the arrow of the right arrow becomes - relatively-smaller, and the arrow of the left arrow is beautifully beautiful:
So, is there a way to have an open and scaled arrow?
source to share
The key is to use the argument overhang
and set it to 1 or something close to it.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(4,4))
v = [-0.2, 0, .2, .4, .6, .8, 1]
for i, overhang in enumerate(v):
ax.arrow(.1,overhang,.6,0, width=0.001, color="k",
head_width=0.1, head_length=0.15, overhang=overhang)
ax.set_yticks(v)
ax.set_xticks([])
ax.set_ylabel("overhang")
ax.set_ylim(-0.3,1.1)
plt.tight_layout()
plt.show()
source to share