首页 > 解决方案 > 消除python matplotlib中某些限制之外的部分圆圈?

问题描述

我写了这段代码来绘制图像:

fig = plt.figure(figsize=(15,10))
ax = fig.gca(projection='3d')
for i in range(len(pos_eje_x)):
    ax.bar3d(pos_eje_x[i],pos_eje_y[i],z_altura[i], dx[i], dy[i], altura[i], alpha=1, color='w', linewidth=2)

ax.scatter(200, 500, 500, color='r', marker='^', s=150)

circle_1 = Circle((200, 500), 500*np.tan(np.deg2rad(60 / 2)), fill=False, clip_on=False)
ax.add_patch(circle_1)
art3d.pathpatch_2d_to_3d(circle_1, z=25, zdir="z")

ax.autoscale()
ax.set_zlim3d(0, 1000)
ax.set_xlim3d(0, L)
ax.set_ylim3d(0, L)
ax.set_xlim(0, L)
ax.set_ylim(0, L)
ax.set_zlim(0, 1000)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.title('Map 3D')
ax.view_init(elev=30., azim=-35)

这是我的输出:

绘制 3d

如何删除超出范围的圆圈的其余部分?

标签: pythonmatplotlib

解决方案


您可以手动绘制一个圆圈,然后将不在限制范围内的部分剪掉。不过,您必须注意,披萨片的起点和终点位于正确的位置,否则会产生额外的不必要的连接。

import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.art3d as art3d  # noqa: F401 unused import

def get_circle(x, r, n=360):
    q = np.linspace(start=-np.pi, stop=np.pi, num=n)

    c = np.empty((n, len(x)))
    c[:, 0] = np.cos(q)*r + x[0]
    c[:, 1] = np.sin(q)*r + x[1]
    if len(x) == 3:
        c[:, 2] = x[2]

    return c

def cut_circle(c, limits):
    idx_keep_x = np.logical_and(limits[0, 0] < c[:, 0], c[:, 0] < limits[0, 1])
    idx_keep_y = np.logical_and(limits[1, 0] < c[:, 1], c[:, 1] < limits[1, 1])
    idx_keep = np.logical_and(idx_keep_x, idx_keep_y)

    c2 = c[idx_keep, :]

    c2_help = np.concatenate([c2, c2[:1, :]])
    i_jump = np.argmax(np.linalg.norm(np.diff(c2_help[:, :2], axis=0), axis=-1))

    c3 = np.roll(c2, -(i_jump+1), axis=0)

    return c2, c3


limits = np.array([[20, 50],
                   [30, 60],
                   [0, 20]])

c1 = get_circle(x=[45, 55, 5], r=10)
c2, c3 = cut_circle(c=c1, limits=limits)

c2[:,  2] += 5
c3[:, 2] += 10


fig = plt.figure()
ax = fig.gca(projection='3d')

ax.set_xlim(limits[0])
ax.set_ylim(limits[1])
ax.set_zlim(limits[2])

ax.plot(*c1.T)
ax.plot(*c2.T)
ax.plot(*c3.T)


推荐阅读