gpt4 book ai didi

Python Matplotlib - 绘制长方体

转载 作者:行者123 更新时间:2023-12-03 20:30:33 57 4
gpt4 key购买 nike

我正在尝试使用 matplotlib 绘制不同大小的长方体,这样:旋转后,长方体不会以非物理方式在视觉上重叠,立方体具有不同的颜色并在它们周围绘制一个框。

我已经阅读了几篇引用类似问题的博客文章和 stackoverflow 页面,但总是略有不同;没有一个对我有用。克服重叠问题的最简单方法是使用体素(如 https://matplotlib.org/api/_as_gen/mpl_toolkits.mplot3d.axes3d.Axes3D.html?highlight=voxel#mpl_toolkits.mplot3d.axes3d.Axes3D.voxels ),但这些不允许我在它们周围绘制框。在 matplotlib 中最简单的方法是什么?

下图显示了我在左边的东西,以及我想要的东西在右边。

编辑:
我研究了几种可以达到预期效果的方法,其中主要的方法是:

  • 使用体素,但以某种方式缩放它们,使单个体素代表单个项目。
  • 使用曲面图,然后动态调整绘图顺序以避免非物理重叠。

  • 前者似乎更容易执行,但我仍然很难过。

    Left: what I get. Right: what I want

    最佳答案

    A. 使用 Poly3DCollection一个选项是创建一个 Poly3DCollection长方体的面。由于同一收藏的艺术家不存在重叠问题,因此这可能最适合这里的目的。

    from mpl_toolkits.mplot3d import Axes3D
    from mpl_toolkits.mplot3d.art3d import Poly3DCollection
    import numpy as np
    import matplotlib.pyplot as plt

    def cuboid_data2(o, size=(1,1,1)):
    X = [[[0, 1, 0], [0, 0, 0], [1, 0, 0], [1, 1, 0]],
    [[0, 0, 0], [0, 0, 1], [1, 0, 1], [1, 0, 0]],
    [[1, 0, 1], [1, 0, 0], [1, 1, 0], [1, 1, 1]],
    [[0, 0, 1], [0, 0, 0], [0, 1, 0], [0, 1, 1]],
    [[0, 1, 0], [0, 1, 1], [1, 1, 1], [1, 1, 0]],
    [[0, 1, 1], [0, 0, 1], [1, 0, 1], [1, 1, 1]]]
    X = np.array(X).astype(float)
    for i in range(3):
    X[:,:,i] *= size[i]
    X += np.array(o)
    return X

    def plotCubeAt2(positions,sizes=None,colors=None, **kwargs):
    if not isinstance(colors,(list,np.ndarray)): colors=["C0"]*len(positions)
    if not isinstance(sizes,(list,np.ndarray)): sizes=[(1,1,1)]*len(positions)
    g = []
    for p,s,c in zip(positions,sizes,colors):
    g.append( cuboid_data2(p, size=s) )
    return Poly3DCollection(np.concatenate(g),
    facecolors=np.repeat(colors,6), **kwargs)


    positions = [(-3,5,-2),(1,7,1)]
    sizes = [(4,5,3), (3,3,7)]
    colors = ["crimson","limegreen"]

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

    pc = plotCubeAt2(positions,sizes,colors=colors, edgecolor="k")
    ax.add_collection3d(pc)

    ax.set_xlim([-4,6])
    ax.set_ylim([4,13])
    ax.set_zlim([-3,9])

    plt.show()
    enter image description here
    B. 使用 plot_surface调整来自 this question 的解决方案, 使用 plot_surface , 并根据需要允许不同的大小,在大多数情况下似乎可以正常工作:
    from mpl_toolkits.mplot3d import Axes3D
    import numpy as np
    import matplotlib.pyplot as plt

    def cuboid_data(o, size=(1,1,1)):
    # code taken from
    # https://stackoverflow.com/a/35978146/4124317
    # suppose axis direction: x: to left; y: to inside; z: to upper
    # get the length, width, and height
    l, w, h = size
    x = [[o[0], o[0] + l, o[0] + l, o[0], o[0]],
    [o[0], o[0] + l, o[0] + l, o[0], o[0]],
    [o[0], o[0] + l, o[0] + l, o[0], o[0]],
    [o[0], o[0] + l, o[0] + l, o[0], o[0]]]
    y = [[o[1], o[1], o[1] + w, o[1] + w, o[1]],
    [o[1], o[1], o[1] + w, o[1] + w, o[1]],
    [o[1], o[1], o[1], o[1], o[1]],
    [o[1] + w, o[1] + w, o[1] + w, o[1] + w, o[1] + w]]
    z = [[o[2], o[2], o[2], o[2], o[2]],
    [o[2] + h, o[2] + h, o[2] + h, o[2] + h, o[2] + h],
    [o[2], o[2], o[2] + h, o[2] + h, o[2]],
    [o[2], o[2], o[2] + h, o[2] + h, o[2]]]
    return np.array(x), np.array(y), np.array(z)

    def plotCubeAt(pos=(0,0,0), size=(1,1,1), ax=None,**kwargs):
    # Plotting a cube element at position pos
    if ax !=None:
    X, Y, Z = cuboid_data( pos, size )
    ax.plot_surface(X, Y, Z, rstride=1, cstride=1, **kwargs)

    positions = [(-3,5,-2),(1,7,1)]
    sizes = [(4,5,3), (3,3,7)]
    colors = ["crimson","limegreen"]


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

    for p,s,c in zip(positions,sizes,colors):
    plotCubeAt(pos=p, size=s, ax=ax, color=c)

    plt.show()
    enter image description here

    关于Python Matplotlib - 绘制长方体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49277753/

    57 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com