Python 是否有方法在matplotlib中标记多个三维曲面?

Python 是否有方法在matplotlib中标记多个三维曲面?,python,matplotlib,Python,Matplotlib,我试图解决一个具有线性约束的非线性数学优化问题。为此,我尝试在3d中可视化约束,以了解发生了什么,以及为什么我得到约束中某些参数的可行解决方案,而不是其他参数的可行解决方案 为了实现这一点,我想使用python中的matplotlib生成3d曲面(平面,因为我所有的约束都是线性的) 但是,如果没有图内标记,则很难识别哪个曲面属于哪个约束。这让我想寻找一种方法,在情节中添加带有颜色的图例 我认识到在2D中,在方法ax.plot()或ax.scatter()中已经有一种方法可以做到这一点,但尝试这样

我试图解决一个具有线性约束的非线性数学优化问题。为此,我尝试在3d中可视化约束,以了解发生了什么,以及为什么我得到约束中某些参数的可行解决方案,而不是其他参数的可行解决方案

为了实现这一点,我想使用python中的matplotlib生成3d曲面(平面,因为我所有的约束都是线性的)

但是,如果没有图内标记,则很难识别哪个曲面属于哪个约束。这让我想寻找一种方法,在情节中添加带有颜色的图例

我认识到在2D中,在方法
ax.plot()
ax.scatter()
中已经有一种方法可以做到这一点,但尝试这样做对
ax.plot_曲面(X,Y,Z,label='mylabel')

全文如下:


从mpl_工具包导入mplot3d
从mpl_toolkits.mplot3d导入Axes3D
将matplotlib.pyplot作为plt导入
将numpy作为np导入
图=plt.图()
ax=plt.轴(投影='3d')
plt.rcParams['legend.fontsize']=10
#第一约束
g2=np.linspace(-5,5,2)
g3=np.linspace(-5,5,2)
G2,G3=np.网格(G2,G3)
G4_1=-1.18301270189222-0.5*G2+0.5*G3
ax=图gca(投影=3d')
c1=最大绘图曲面(G2、G3、G4\U 1,label=“c1”)
#第二
G3,G4=np.网格(g2,G3)
G2=G3
c2=最大绘图曲面(G2、G3、G4,label=“c2”)
#第三
G2,G3=np.网格(G2,G3)
G4=(0.408248290463863*G2+0.408248290463863*G3-0.707106781186548)/1.63299316185545
c3=最大绘图曲面(G2、G3、G4,label=“c3”)
#来回
G4=(1.04903810567666-(0.2886715134594813*G2+0.2886715134594813*G3))/0.577350269189626
c4=最大图面(G2、G3、G4,label=“c4”)
ax.legend()#->错误:“AttributeError:“Poly3DCollection”对象没有属性“\u edgecolors2d”
#标记图形
图1标题(“约束”)
#plt.xlabel('g2',fontsize=14)
#plt.ylabel('g3',fontsize=14)
ax.set_xlabel(r'$g_2$',fontsize=15,旋转=60)
ax.set_ylabel(“$g_3$”,fontsize=15,rotation=60)
ax.set_zlabel(“$g_4$”,fontsize=15,rotation=60)
plt.savefig('Constraints.jpg'))
plt.show()
这将导致下图

正如您可能已经看到的,无法判断哪个曲面属于哪个约束,我想要实现的是一个图例,如

我通读了的答案,但在这里不起作用,因为我有多个曲面。试用后,它只显示一个标签,而不是四个

所以我的问题是,有没有办法在我的
ax.plot\u surface
或任何其他合适的破解中添加图例?

解决方案是在此错误中:
ax.legend()#->错误:“AttributeError:'Poly3DCollection'对象没有属性“\u edgecolors2d”

我相信这是一只虫子

如果探索任何曲面对象(比如说
c1
),可以看到它们具有属性
“U edgecolors3d”
,这是创建图例时应该调用的属性

因此,我们只需创建一个名为
“U edgecolors2d”
的新属性,其内容与
“U edgecolors3d”
相同

一旦
“U-edgecolors2d”
问题解决,您将遇到一个新的
“U-facecolors2d”
。我们重复同样的步骤,就完成了


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

plt.rcParams['legend.fontsize'] = 10


# First constraint
g2 = np.linspace(-5,5,2)
g3 = np.linspace(-5,5,2)
G2,G3 = np.meshgrid(g2,g3)
G4_1 = -1.18301270189222 - 0.5*G2 + 0.5*G3
ax = fig.gca(projection='3d')
c1 = ax.plot_surface(G2, G3, G4_1, label = "c1")
c1._facecolors2d=c1._facecolors3d
c1._edgecolors2d=c1._edgecolors3d

# Second
G3, G4 = np.meshgrid(g2, g3)
G2 = G3
c2 = ax.plot_surface(G2, G3, G4, label = "c2")
c2._facecolors2d=c2._facecolors3d
c2._edgecolors2d=c2._edgecolors3d

# Third
G2,G3 = np.meshgrid(g2,g3)
G4 = (0.408248290463863*G2 + 0.408248290463863*G3 -0.707106781186548)/1.63299316185545
c3 = ax.plot_surface(G2, G3, G4, label = "c3")
c3._facecolors2d=c3._facecolors3d
c3._edgecolors2d=c3._edgecolors3d

# And forth
G4 = (1.04903810567666 - (0.288675134594813*G2 + 0.288675134594813*G3))/0.577350269189626
c4 = ax.plot_surface(G2, G3, G4, label="c4")

c4._facecolors2d=c4._facecolors3d
c4._edgecolors2d=c4._edgecolors3d

ax.legend() # -> error : 'AttributeError: 'Poly3DCollection' object has no attribute '_edgecolors2d''


# labeling the figure
fig.suptitle("Constraints")
#plt.xlabel('g2', fontsize=14)
#plt.ylabel('g3', fontsize=14)
ax.set_xlabel(r'$g_2$', fontsize=15, rotation=60)
ax.set_ylabel('$g_3$', fontsize=15, rotation=60)
ax.set_zlabel('$g_4$', fontsize=15, rotation=60)
plt.savefig('Constraints.jpg')
plt.show()

这是对@Gio答案的更新。从
matplotlib 3.3.3
开始,
\u facecolors3d
\u edgecolors3d
不存在。因此,与此相反:

c1._facecolors2d = c1._facecolors3d
c1._edgecolors2d = c1._edgecolors3d
这将导致类似的
属性错误
,请尝试以下操作:

c1._facecolors2d = c1._facecolor3d
c1._edgecolors2d = c1._edgecolor3d
我不得不回答这个问题,而不是发表评论,因为我的代表性不高。

这肯定是不知何故忘记的。