【问题标题】:How to fill a 3D triangle with a color gradient如何用颜色渐变填充 3D 三角形
【发布时间】:2026-01-25 00:05:01
【问题描述】:

我正在尝试将颜色图应用于 3d 多边形。 多边形很好,显示在正确的位置。 我唯一不能做的就是用渐变填充它。

这是我的代码:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.colors import LinearSegmentedColormap
from mpl_toolkits.mplot3d.art3d import Poly3DCollection

fig = plt.figure()
ax = Axes3D(fig)

x = [0,0,0]
y = [0,1,0]
z = [0,0,1]
verts = [zip(x, y,z)] #(0,0,0) (0,1,0) (0,0,1)

colors = ['red', 'gray', 'gray', 'green']
index  = [0.0, 0.49, 0.509, 1.0]
cm = LinearSegmentedColormap.from_list('my_colormap', zip(index, colors))

collection = Poly3DCollection(verts, cmap=cm)
ax.add_collection3d(collection)
plt.show()

有人可以帮帮我吗?

编辑:

此外,渐变应该看起来像this

【问题讨论】:

    标签: python matplotlib 3d polygon


    【解决方案1】:

    由于集合的每个成员只能有一个与之关联的颜色,因此不能简单地使用三角形来实现渐变填充。

    获得三角形渐变的一种方法是使用plt.contourf

    from mpl_toolkits.mplot3d import axes3d
    import matplotlib.pyplot as plt
    import numpy as np
    
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    
    X, Y = np.meshgrid(np.linspace(0,1), np.linspace(0,1)) 
    Z = 1.-X-Y
    Z[Z<0] = 0
    
    cset = ax.contourf(X, Y, Z, zdir='x', levels=np.linspace(0,1),offset=0, cmap=plt.cm.jet)
    ax.set_xlabel('X')
    ax.set_xlim(0, 1)
    ax.set_ylabel('Y')
    ax.set_ylim(0,1)
    ax.set_zlabel('Z')
    ax.set_zlim(0,1)    
    plt.show()
    

    在这里,contourf 的使用有点小技巧。为了获得其他方向的梯度,最好使用曲面图 (plot_surface)。

    from mpl_toolkits.mplot3d import axes3d
    import matplotlib.pyplot as plt
    import numpy as np
     
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    points=50
    Y, Z = np.meshgrid(np.linspace(0,1,points), np.linspace(0,1,points)) 
    Z = Z*(1-Y)
    color =(1-Y+Z)*0.5
    
    ax.plot_surface(np.zeros_like(Y), Y, Z, facecolors=plt.cm.jet(color), 
                    rcount=points, ccount=points, shade=False)
    
    ax.set_xlabel('X')
    ax.set_xlim(0, 1)
    ax.set_ylabel('Y')
    ax.set_ylim(0,1)
    ax.set_zlabel('Z')
    ax.set_zlim(0,1)    
    plt.show()
    

    为了获得更平滑的画面,可以增加points,但这也可能会显着增加绘制时间。

    【讨论】:

    • 这正是我想要的。非常感谢@ImportanceOfBeingErnest
    • 现在完美了!
    最近更新 更多