Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在matplotlib中生成循环箭头?_Python_Matplotlib - Fatal编程技术网

Python 如何在matplotlib中生成循环箭头?

Python 如何在matplotlib中生成循环箭头?,python,matplotlib,Python,Matplotlib,在matplotlib中绘制循环指向其原点的箭头的正确方法是什么?我试过: plt.figure() plt.xlim([0, 1]) plt.ylim([0, 1]) plt.annotate("", xy=(0.6, 0.9), xycoords="figure fraction", xytext = (0.6, 0.8), textcoords="figure fraction", fo

在matplotlib中绘制循环指向其原点的箭头的正确方法是什么?我试过:

plt.figure()
plt.xlim([0, 1])
plt.ylim([0, 1])
plt.annotate("", xy=(0.6, 0.9),
             xycoords="figure fraction",
             xytext = (0.6, 0.8),
             textcoords="figure fraction",
             fontsize = 10, \
             color = "k",
             arrowprops=dict(edgecolor='black',
                             connectionstyle="angle,angleA=-180,angleB=45",
                             arrowstyle = '<|-',
                             facecolor="k",
                             linewidth=1,
                             shrinkA = 0,
                             shrinkB = 0))
plt.show()
plt.figure()
plt.xlim([0,1])
plt.ylim([0,1])
plt.注释(“,xy=(0.6,0.9),
xycoords=“数字分数”,
xytext=(0.6,0.8),
textcoords=“数字分数”,
fontsize=10\
color=“k”,
arrowprops=dict(edgecolor='black',
connectionstyle=“角度,角度A=-180,角度B=45”,
arrowstyle='试试这个:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.set_xlim(1,3) 
ax.set_ylim(1,3)
ax.plot([2.5],[2.5],marker=r'$\circlearrowleft$',ms=100)
plt.show()

创建易于修改的循环箭头的最简单方法似乎是使用。我在下面粘贴了代码来完成此操作。在变量部分更改变量,所有内容都应该一起旋转和缩放。您可以使用创建箭头的补丁来制作不同的形状,尽管我怀疑这个三角形这是最容易的

%matplotlib inline
# from __future__ import division #Uncomment for python2.7
import matplotlib.pyplot as plt
from matplotlib.patches import Arc, RegularPolygon
import numpy as np
from numpy import radians as rad

fig = plt.figure(figsize=(9,9))
ax = plt.gca()
def drawCirc(ax,radius,centX,centY,angle_,theta2_,color_='black'):
    #========Line
    arc = Arc([centX,centY],radius,radius,angle=angle_,
          theta1=0,theta2=theta2_,capstyle='round',linestyle='-',lw=10,color=color_)
    ax.add_patch(arc)


    #========Create the arrow head
    endX=centX+(radius/2)*np.cos(rad(theta2_+angle_)) #Do trig to determine end position
    endY=centY+(radius/2)*np.sin(rad(theta2_+angle_))

    ax.add_patch(                    #Create triangle as arrow head
        RegularPolygon(
            (endX, endY),            # (x,y)
            3,                       # number of vertices
            radius/9,                # radius
            rad(angle_+theta2_),     # orientation
            color=color_
        )
    )
    ax.set_xlim([centX-radius,centY+radius]) and ax.set_ylim([centY-radius,centY+radius]) 
    # Make sure you keep the axes scaled or else arrow will distort

drawCirc(ax,1,1,1,0,250)
drawCirc(ax,2,1,1,90,330,color_='blue')
plt.show()    

我的建议只使用plot命令

import matplotlib.pyplot as plt
import numpy as np


def circarrowdraw(x0, y0, radius=1, aspect=1, direction=270, closingangle=-330,
                  arrowheadrelativesize=0.3, arrowheadopenangle=30, *args):
    """
    Circular arrow drawing. x0 and y0 are the anchor points.
    direction gives the angle of the circle center relative to the anchor
    in degrees. closingangle indicates how much of the circle is drawn
    in degrees with positive being counterclockwise and negative being
    clockwise. aspect is important to make the aspect of the arrow 
    fit the current figure.
    """

    xc = x0 + radius * np.cos(direction * np.pi / 180)
    yc = y0 + aspect * radius * np.sin(direction * np.pi / 180)

    headcorrectionangle = 5

    if closingangle < 0:
        step = -1
    else:
        step = 1
    x = [xc + radius * np.cos((ang + 180 + direction) * np.pi / 180)
         for ang in np.arange(0, closingangle, step)]
    y = [yc + aspect * radius * np.sin((ang + 180 + direction) * np.pi / 180)
         for ang in np.arange(0, closingangle, step)]

    plt.plot(x, y, *args)

    xlast = x[-1]
    ylast = y[-1]

    l = radius * arrowheadrelativesize

    headangle = (direction + closingangle + (90 - headcorrectionangle) *
                 np.sign(closingangle))

    x = [xlast +
         l * np.cos((headangle + arrowheadopenangle) * np.pi / 180),
         xlast,
         xlast +
         l * np.cos((headangle - arrowheadopenangle) * np.pi / 180)]
    y = [ylast +
         aspect * l * np.sin((headangle + arrowheadopenangle) * np.pi / 180),
         ylast,
         ylast +
         aspect * l * np.sin((headangle - arrowheadopenangle) * np.pi / 180)]

    plt.plot(x, y, *args)

我发现无法使用
plt进行循环。只需注释一次
,但使用四次即可:

import matplotlib.pyplot as plt

fig,ax = plt.subplots()

# coordinates of the center of the loop
x_center = 0.5 
y_center = 0.5 

radius = 0.2
# linewidth of the arrow
linewidth = 1

ax.annotate("", (x_center + radius, y_center), (x_center, y_center + radius),
            arrowprops=dict(arrowstyle="-",
                            shrinkA=10,  # creates a gap between the start point and end point of the arrow
                            shrinkB=0,
                            linewidth=linewidth,
                            connectionstyle="angle,angleB=-90,angleA=180,rad=10"))    

ax.annotate("", (x_center, y_center - radius), (x_center + radius, y_center), 
            arrowprops=dict(arrowstyle="-",
                            shrinkA=0, 
                            shrinkB=0,
                            linewidth=linewidth,
                            connectionstyle="angle,angleB=180,angleA=-90,rad=10"))    

ax.annotate("", (x_center - radius, y_center),  (x_center, y_center - radius), 
            arrowprops=dict(arrowstyle="-",
                            shrinkA=0, 
                            shrinkB=0,
                            linewidth=linewidth,
                            connectionstyle="angle,angleB=-90,angleA=180,rad=10"))    
ax.annotate("", (x_center, y_center + radius), (x_center - radius, y_center), 
            arrowprops=dict(arrowstyle="-|>",
                            facecolor="k",
                            linewidth=linewidth,
                            shrinkA=0, 
                            shrinkB=0,
                            connectionstyle="angle,angleB=180,angleA=-90,rad=10"))


plt.show()

另一种可能性是使用tikz生成图形:

    \documentclass {minimal}
    \usepackage {tikz}
    \begin{document}
    \usetikzlibrary {arrows}
    \begin {tikzpicture}[scale=1.8]
    \draw[-angle 90, line width=5.0mm, rounded corners=20pt] 
    (0.25,0)--   (1.0, 0.0) -- (1.0, -3.0) -- (-3.0, -3.0) -- (-3.0, 0) --(-1,0);
    \end{tikzpicture}
    \end{document}
结果是:

matplotlib中有一个pgf/tikz后端,您可以将matplotlib输出生成pdflatex或lualatex可以处理的tikz代码。 这样,我想,你可以无缝地插入looparrow图形 你的matplotlib图。 例如,见:

@Aguy的答案非常有用,如果你想要一个平滑的圆弧而不是一个完整的圆。在Aguy的答案中,箭头是一行一行地画出来的,但是可以使用FancyRowPatch。这会给出一个完整的箭头,这可能更合适。下面给出了FancyRowPatch箭头的代码

def circarrowdraw(x0, y0, radius=1, aspect=1, direction=270, closingangle=-330, rotate_head = 0.0, color='b', *args):
    """
    Circular arrow drawing. x0 and y0 are the anchor points.
    direction gives the angle of the circle center relative to the anchor
    in degrees. closingangle indicates how much of the circle is drawn
    in degrees with positive being counterclockwise and negative being
    clockwise. aspect is important to make the aspect of the arrow 
    fit the current figure. rotate_head is used to rotate the arrow head
    by increasing the y value of the arrow's tail coordinate.
    """

    # Center of circle
    xc = x0 + radius * np.cos(direction * np.pi / 180)
    yc = y0 + aspect * radius * np.sin(direction * np.pi / 180)

    # Draw circle
    if closingangle < 0:
        step = -1
    else:
        step = 1
    x = [xc + radius * np.cos((ang + 180 + direction) * np.pi / 180)
         for ang in np.arange(0, closingangle, step)]
    y = [yc + aspect * radius * np.sin((ang + 180 + direction) * np.pi / 180)
         for ang in np.arange(0, closingangle, step)]
    plt.plot(x, y, *args, color=color)

    # Draw arrow head
    arc_arrow_head = patches.FancyArrowPatch((x[-1], y[-1] + rotate_head),
                                             (x[0], y[0]),
                                             arrowstyle="Simple,head_width=10,head_length=10,tail_width=0.01", 
                                             color = color,
                                             zorder = 10)
    plt.gca().add_patch(arc_arrow_head)

我希望使用
plt.annotate
中的箭头样式,而不是此箭头。此外,这在角度或箭头大小等方面没有灵活性。您的解决方案还依赖于tex和tex的字体。
def circarrowdraw(x0, y0, radius=1, aspect=1, direction=270, closingangle=-330, rotate_head = 0.0, color='b', *args):
    """
    Circular arrow drawing. x0 and y0 are the anchor points.
    direction gives the angle of the circle center relative to the anchor
    in degrees. closingangle indicates how much of the circle is drawn
    in degrees with positive being counterclockwise and negative being
    clockwise. aspect is important to make the aspect of the arrow 
    fit the current figure. rotate_head is used to rotate the arrow head
    by increasing the y value of the arrow's tail coordinate.
    """

    # Center of circle
    xc = x0 + radius * np.cos(direction * np.pi / 180)
    yc = y0 + aspect * radius * np.sin(direction * np.pi / 180)

    # Draw circle
    if closingangle < 0:
        step = -1
    else:
        step = 1
    x = [xc + radius * np.cos((ang + 180 + direction) * np.pi / 180)
         for ang in np.arange(0, closingangle, step)]
    y = [yc + aspect * radius * np.sin((ang + 180 + direction) * np.pi / 180)
         for ang in np.arange(0, closingangle, step)]
    plt.plot(x, y, *args, color=color)

    # Draw arrow head
    arc_arrow_head = patches.FancyArrowPatch((x[-1], y[-1] + rotate_head),
                                             (x[0], y[0]),
                                             arrowstyle="Simple,head_width=10,head_length=10,tail_width=0.01", 
                                             color = color,
                                             zorder = 10)
    plt.gca().add_patch(arc_arrow_head)
plt.plot([0, 0, 1, 1, 0], [0, 1, 1, 0, 0])
circarrowdraw(1.0, 1.0 , radius=0.1, aspect=0.3, direction=90, closingangle=-345, rotate_head = 0.003)
circarrowdraw(0.0, 1.0 , radius=0.1, aspect=1, direction=-90, closingangle=-345, rotate_head = 0.0)
circarrowdraw(0.0, 0.0 , radius=0.1, aspect=3.0, direction=90, closingangle=-345, rotate_head = 0.01)
circarrowdraw(1.0, 0.0 , radius=0.1, aspect=0.3, direction=-90, closingangle=-345)
plt.show()