在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()
这并没有给出正确的结果:
connectionstyle
参数很难从此页面(http://matplotlib.org/users/annotations_guide.html)开始。
更新:链接到的答案未显示如何与plt.annotate
具有我想要使用的其他功能。使用$\circlearrowleft$
标记的提议不是真正的解决方案。
答案 0 :(得分:7)
我发现只能使用plt.annotate
进行一次循环,但是使用它四次就可以了:
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()
答案 1 :(得分:5)
创建易于修改的循环箭头似乎最简单的方法是使用patches。我已粘贴代码以执行此操作。更改变量部分中的变量,事物应该全部旋转并缩放。您可以使用创建箭头的补丁来制作不同的形状,但我怀疑这个三角形是最简单的。
%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()
答案 2 :(得分:3)
答案 3 :(得分:3)
我的建议只使用了绘图命令
import org.hibernate.boot.model.naming.Identifier;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.CRC32;
/**
* Based on:
* Doctrine\DBAL\Schema\Table
* Doctrine\DBAL\Schema\AbstractAsset
*/
public class DoctrineNamingHelper {
public static final DoctrineNamingHelper INSTANCE = new DoctrineNamingHelper();
private static Integer MAX_LENGTH=63;
/*
FK:
$name = $this->_generateIdentifierName(
array_merge((array) $this->getName(), $constraint->getLocalColumns()), "fk", $this->_getMaxIdentifierLength()
);
IDX:
$indexName = $this->_generateIdentifierName(
array_merge(array($this->getName()), $constraint->getColumns()),
"idx",
$this->_getMaxIdentifierLength()
);
$indexName = $this->_generateIdentifierName(
array_merge(array($this->getName()), $columnNames), "idx", $this->_getMaxIdentifierLength()
);
UNIQ:
$indexName = $this->_generateIdentifierName(
array_merge(array($this->getName()), $columnNames), "uniq", $this->_getMaxIdentifierLength()
);
*/
public String generateHashedFkName( String prefix, Identifier tableName, Identifier referencedTableName, List<Identifier> columnNames){
List<Identifier> parts = new ArrayList<>();
parts.add(tableName);
parts.addAll(columnNames);
return makeHash(prefix, parts, MAX_LENGTH) ;
}
public String generateHashedConstraintName(String prefix, Identifier tableName, List<Identifier> columnNames) {
List<Identifier> parts = new ArrayList<>();
parts.add(tableName);
parts.addAll(columnNames);
return makeHash(prefix,parts, MAX_LENGTH) ;
}
private String makeHash(String prefix, List<Identifier> parts, Integer maxSize){
// Based on Doctrine\DBAL\Schema\AbstractAsset::_generateIdentifierName()
String hash = prefix;
for(Identifier part: parts)
{
CRC32 crc32=new CRC32();
crc32.update(part.getText().getBytes());
String hexed=Integer.toHexString((int)crc32.getValue());
hash += hexed;
}
if (hash.length()>maxSize) {
hash = hash.substring(0, maxSize);
}
return hash;
}
}
测试它:
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)
答案 4 :(得分:1)
另一种可能性是使用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图。 见ex: http://matplotlib.org/users/whats_new.html#pgf-tikz-backend
答案 5 :(得分:0)
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()
Picture of image (I don't have a high enough reputation to embed the image in my answer)