带有 TikZ 样式路径装饰的 Matplotlib 注释箭头

Matplotlib annotation arrow with TikZ style path decoration

我最近从使用 TeX (PGF/TikZ) 制作插图转为使用 Matplotlib 来达到同样的目的。主要是我的很多科学代码都在python里面,有的插图应该直接用python计算的输出。

我一直在使用 annotate and the fancy arrow patch, which already does a lot of what I need, such as drawing curved arrows (see e.g. ). Compared to TikZ, there is one particular thing I have been missing: path decorations (see e.g. https://tex.stackexchange.com/a/193451/96546 作为简单的 TikZ 示例)。 我的问题是是否有办法在 matplotlib 中进行这种 TikZ 风格的路径装饰?

由于这相当广泛,我将设置一个特定的任务(取自 TeX.SE 问题 https://tex.stackexchange.com/questions/193444/sketching-simple-arrows-with-different-direction):我将如何在 Matplotlib 中绘制以下图片?

我知道 问题,但实现并不是端点之间的线装饰,而是绘制的函数。

我在 feynman package by GkAntonius (docs) 的帮助下在 matplotlib 中创建了这个。这具有使用顶点和线(包括 style='wiggly' 线型)整齐绘制各种箭头类型的功能。我还向这些波浪线添加了直线开始和结束段,如 OP 中的示例图所示。此外,鉴于 comments/bounty 要求 curved/arch 摆动线,我还提供了此功能的演示。

有问题的图表

代码:

import matplotlib.pyplot as plt
from feynman import Diagram

# Set up diagram
fig = plt.figure(figsize=(10.,10.))
ax = fig.add_axes([0,0,1,1], frameon=False)
diagram = Diagram(ax)

# Mirror line
m1 = diagram.vertex(xy=(.1,.5), marker='')
m2 = diagram.vertex(xy=(.9,.5), marker='')
mirror = diagram.line(m1, m2, arrow=False, style='double')


# Top left P-line
p1 = diagram.vertex(xy=(.2, .8), marker='')
p2 = diagram.vertex(xy=(.5, .5), marker='')
P1 = diagram.line(p1, p2, arrow=True, arrow_param={'t':0.91})
P1.text("$P$", fontsize=60, y=-.1, t=.1)


# Bottom right P-line
p3 = diagram.vertex(xy=(.5, .5), marker='')
p4 = diagram.vertex(xy=(.8, .2), marker='')
P2 = diagram.line(p3, p4, arrow=True, arrow_param={'t':0.91})
P2.text("$P$", fontsize=60, y=.05, t=.9)


# Top right P-line
p5 = diagram.vertex(xy=(.5, .5), marker='')
p6 = diagram.vertex(xy=(.8, .8), marker='')
P3 = diagram.line(p5, p6, arrow=True, arrow_param={'t':0.91})
P3.text("$P$", fontsize=60, y=-.05, t=.9)


# Top right SV-line start
sv1_s1 = diagram.vertex(xy=(.5, .5), marker='')
sv1_s2 = diagram.vertex(xy=(.51, .5175), marker='')
SV1_start = diagram.line(sv1_s1, sv1_s2, arrow=False)

# Top right SV-line middle
sv1_1 = diagram.vertex(xy=(.51, .5175), marker='')
sv1_2 = diagram.vertex(xy=(.69, .8325), marker='')
SV1 = diagram.line(sv1_1, sv1_2, arrow=False, style='wiggly', nwiggles=5)
SV1.text("$SV$", fontsize=60, y=.15, t=.9)

# Top right SV-line end
sv1_e1 = diagram.vertex(xy=(.69, .8325), marker='')
sv1_e2 = diagram.vertex(xy=(.7, .85), marker='')
SV1_end = diagram.line(sv1_e1, sv1_e2, arrow=True, arrow_param={'t':0.91})


# Bottom right SV-line start
sv2_s1 = diagram.vertex(xy=(.5, .5), marker='')
sv2_s2 = diagram.vertex(xy=(.51, .4825), marker='')
SV2_start = diagram.line(sv2_s1, sv2_s2, arrow=False)

# Bottom right SV-line middle
sv2_1 = diagram.vertex(xy=(.51, .4825), marker='')
sv2_2 = diagram.vertex(xy=(.69, .1675), marker='')
SV2 = diagram.line(sv2_1, sv2_2, arrow=False, style='wiggly', nwiggles=5)
SV2.text("$SV$", fontsize=60, y=-.15, t=.9)

# Bottom right SV-line end
sv2_e1 = diagram.vertex(xy=(.69, .1675), marker='')
sv2_e2 = diagram.vertex(xy=(.7, .15), marker='')
SV2_end = diagram.line(sv2_e1, sv2_e2, arrow=True, arrow_param={'t':0.91})

diagram.plot()
plt.show()

Curved/arched 行

代码

import matplotlib.pyplot as plt
from feynman import Diagram

# Set up diagram
fig = plt.figure(figsize=(8,8))
ax = fig.add_axes([0,0,1,1], frameon=False)
diagram = Diagram(ax)

# Curvy wiggly line
sv1_1 = diagram.vertex(xy=(.205, .205), marker='')
sv1_2 = diagram.vertex(xy=(.79, .79), marker='')
SV1 = diagram.line(sv1_1, sv1_2, arrow=False, style='wiggly elliptic ', nwiggles=8)
SV1.text("$", fontsize=50, y=.15, t=.5)

# Curvy wiggly line end
sv1_e1 = diagram.vertex(xy=(.79, .79), marker='')
sv1_e2 = diagram.vertex(xy=(.8, .8), marker='')
SV1_end = diagram.line(sv1_e1, sv1_e2, arrow=True, arrow_param={'t':0.91})


# Circular wiggly line
sv2_1 = diagram.vertex(xy=(.75, .25), marker='')
SV2 = diagram.line(sv2_1, sv2_1, arrow=False, style='wiggly circular', nwiggles=8)
SV2.text("$", fontsize=50, y=.15, t=.5)

diagram.plot()
plt.show()