如何在Matplotlib中绘制实心圆弧

Die*_*ich 6 python matplotlib

在matplotlib中,我想绘制一个如下所示的实心圆弧:

实心圆弧示例

以下代码导致未填充的圆弧:

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt

fg, ax = plt.subplots(1, 1)

pac = mpatches.Arc([0, -2.5], 5, 5, angle=0, theta1=45, theta2=135)
ax.add_patch(pac)

ax.axis([-2, 2, -2, 2])
ax.set_aspect("equal")
fg.canvas.draw()
Run Code Online (Sandbox Code Playgroud)

文档说,实心电弧是不可能的。画一个的最好方法是什么?

hit*_*tzg 6

@jeanrjc的解决方案几乎可以带您到那里,但是它添加了一个完全不必要的白色三角形,该三角形也将隐藏其他对象(请参见下图,版本1)。

这是一种更简单的方法,它仅添加一个圆弧多边形:

基本上,我们points沿着圆的边缘(从theta1theta2)创建了一系列点()。这已经足够了,因为我们可以closePolygon构造函数中设置标志,该标志会将最后一条线添加到第一点(创建闭合弧线)。

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import numpy as np

def arc_patch(center, radius, theta1, theta2, ax=None, resolution=50, **kwargs):
    # make sure ax is not empty
    if ax is None:
        ax = plt.gca()
    # generate the points
    theta = np.linspace(np.radians(theta1), np.radians(theta2), resolution)
    points = np.vstack((radius*np.cos(theta) + center[0], 
                        radius*np.sin(theta) + center[1]))
    # build the polygon and add it to the axes
    poly = mpatches.Polygon(points.T, closed=True, **kwargs)
    ax.add_patch(poly)
    return poly
Run Code Online (Sandbox Code Playgroud)

然后我们将其应用:

fig, ax = plt.subplots(1,2)

# @jeanrjc solution, which might hide other objects in your plot
ax[0].plot([-1,1],[1,-1], 'r', zorder = -10)
filled_arc((0.,0.3), 1, 90, 180, ax[0], 'blue')
ax[0].set_title('version 1')

# simpler approach, which really is just the arc
ax[1].plot([-1,1],[1,-1], 'r', zorder = -10)
arc_patch((0.,0.3), 1, 90, 180, ax=ax[1], fill=True, color='blue')
ax[1].set_title('version 2')

# axis settings
for a in ax:
    a.set_aspect('equal')
    a.set_xlim(-1.5, 1.5)
    a.set_ylim(-1.5, 1.5)

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

结果(版本2):

在此处输入图片说明


tmd*_*son 5

您可以fill_between用来实现这一目标

 import matplotlib.patches as mpatches
 import matplotlib.pyplot as plt
 import numpy as np

 fg, ax = plt.subplots(1, 1)

 r=2.
 yoff=-1
 x=np.arange(-1.,1.05,0.05)
 y=np.sqrt(r-x**2)+yoff

 ax.fill_between(x,y,0)

 ax.axis([-2, 2, -2, 2])
 ax.set_aspect("equal")
 fg.canvas.draw()
Run Code Online (Sandbox Code Playgroud)

与r和yoff一起玩以移动弧线

在此处输入图片说明

编辑:

确定,因此您希望能够绘制任意角度?您只需要找到和弦的方程式,而不是使用上面的平线即可。这是一个用于执行此操作的函数:

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import numpy as np

fg, ax = plt.subplots(1, 1)

col='rgbkmcyk'

def filled_arc(center,r,theta1,theta2):

    # Range of angles
    phi=np.linspace(theta1,theta2,100)

    # x values
    x=center[0]+r*np.sin(np.radians(phi))

    # y values. need to correct for negative values in range theta=90--270
    yy = np.sqrt(r-x**2)
    yy = [-yy[i] if phi[i] > 90 and phi[i] < 270 else yy[i] for i in range(len(yy))]

    y = center[1] + np.array(yy)

    # Equation of the chord
    m=(y[-1]-y[0])/(x[-1]-x[0])
    c=y[0]-m*x[0]
    y2=m*x+c

    # Plot the filled arc
    ax.fill_between(x,y,y2,color=col[theta1/45])

# Lets plot a whole range of arcs
for i in [0,45,90,135,180,225,270,315]:
    filled_arc([0,0],1,i,i+45)

ax.axis([-2, 2, -2, 2])
ax.set_aspect("equal")
fg.savefig('filled_arc.png')
Run Code Online (Sandbox Code Playgroud)

这是输出:

在此处输入图片说明


jrj*_*rjc 5

你可以画一个楔子,然后用三角形隐藏它的一部分:

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import numpy as np

def filled_arc(center, radius, theta1, theta2, ax, color):

    circ = mpatches.Wedge(center, radius, theta1, theta2, fill=True, color=color)
    pt1 = (radius * (np.cos(theta1*np.pi/180.)) + center[0],
           radius * (np.sin(theta1*np.pi/180.)) + center[1])
    pt2 = (radius * (np.cos(theta2*np.pi/180.)) + center[0],
           radius * (np.sin(theta2*np.pi/180.)) + center[1])
    pt3 = center
    pol = mpatches.Polygon([pt1, pt2, pt3], color=ax.get_axis_bgcolor(),
                           ec=ax.get_axis_bgcolor(), lw=2 )
    ax.add_patch(circ)
    ax.add_patch(pol)
Run Code Online (Sandbox Code Playgroud)

然后你可以调用它:

fig, ax = plt.subplots(1,2)
filled_arc((0,0), 1, 45, 135, ax[0], "blue")
filled_arc((0,0), 1, 0, 40, ax[1], "blue")
Run Code Online (Sandbox Code Playgroud)

你得到:

填充弧

或者:

fig, ax = plt.subplots(1, 1)
for i in range(0,360,45):
    filled_arc((0,0), 1, i, i+45, ax, plt.cm.jet(i))
Run Code Online (Sandbox Code Playgroud)

你得到:

在此输入图像描述

华泰


小智 5

这是一个更简单的解决方法。在 mpatches.Arc 命令中使用影线参数。如果您使用影线参数重复符号,则会增加图案的密度。我发现如果您使用 6 个破折号,“-”或 6 个点,“.” (其他人可能也工作),然后它会根据需要牢固地填充弧线。当我运行这个

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt 

plt.axes()
pac = mpatches.Arc([0, -2.5], 5, 5, 45, theta1=45, theta2=135, hatch = '......')
plt.gca().add_patch(pac)
pac.set_color('cyan')
plt.axis('equal')
plt.show()
Run Code Online (Sandbox Code Playgroud)

我明白了:

圆弧填充密集的点影线并旋转 45 度只是为了展示