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

Wol*_*ger 5 python diagram drawing matplotlib tikz

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

我一直在使用annotate花哨的箭头补丁,它已经做了很多我需要什么,比如绘图弯箭(例如参见这里)。与 TikZ 相比,我遗漏了一件特别的事情:路径装饰(参见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 中的以下图片?

在此处输入图片说明

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

CDJ*_*DJB 4

我在 GkAntonius 的feynman 包的帮助下在 matplotlib 中创建了这个(文档)。它具有使用顶点和线条(包括style='wiggly'线条样式)整齐地绘制各种箭头类型的功能。我还为这些摆动线添加了直线开始和结束段,如 OP 中的示例图所示。此外,鉴于评论/赏金要求弯曲/拱形摆动线,我还提供了此功能的演示。

有问题的图表

在此输入图像描述

代码:

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()
Run Code Online (Sandbox Code Playgroud)

曲线/拱形线

在此输入图像描述

代码

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("$1$", 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("$2$", fontsize=50, y=.15, t=.5)

diagram.plot()
plt.show()
Run Code Online (Sandbox Code Playgroud)