如何在matplotlib中绘制3D中的3个轮廓线

时间:2018-03-17 21:19:08

标签: python matplotlib 3d contour

我有3个轮廓,由以下内容生成:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy import stats

mean0 = [ 3.1627717, 2.74815376]
cov0  = [[0.44675818, -0.04885433], [-0.04885433, 0.52484173]]
mean1 = [ 6.63373967, 6.82700035]
cov1  = [[ 0.46269969, 0.11528141], [0.11528141, 0.50237073]]
mean2 = [ 7.20726944, 2.61513787]
cov2  = [[ 0.38486096, -0.13042758], [-0.13042758, 0.40928813]]

x = np.linspace(0, 10, 100)
y = np.linspace(0, 10, 100)
X, Y = np.meshgrid(x, y)
Z0 = np.random.random((len(x),len(y)))
Z1 = np.random.random((len(x),len(y)))
Z2 = np.random.random((len(x),len(y)))

def pdf0(arg1,arg2):
    return (stats.multivariate_normal.pdf((arg1,arg2), mean0, cov0))
def pdf1(arg1,arg2):
    return (stats.multivariate_normal.pdf((arg1,arg2), mean1, cov1))
def pdf2(arg1,arg2):
    return (stats.multivariate_normal.pdf((arg1,arg2), mean2, cov2))


for i in range (0, len(x)):
    for j in range(0,len(y)):
        Z0[i,j] = pdf0(x[i],y[j])
        Z1[i,j] = pdf1(x[i],y[j])
        Z2[i,j] = pdf2(x[i],y[j])

Z0=Z0.T
Z1=Z1.T        
Z2=Z2.T

fig3 = plt.figure()
ax3 = fig3.add_subplot(111)
ax3.contour(X,Y,Z0)
ax3.contour(X,Y,Z1)
ax3.contour(X,Y,Z2)
plt.show()

在视觉上,绘制如下:

contours2d

我希望在3D图中绘制所有这些图,但是当我尝试使用:

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')

# 3D plots for each contour.
surf1 = ax.plot_surface(X, Y, Z0, cmap=cm.coolwarm, linewidth=0, antialiased=False)
surf2 = ax.plot_surface(X, Y, Z1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
surf3 = ax.plot_surface(X, Y, Z2, cmap=cm.coolwarm, linewidth=0, antialiased=False)

ax.contour(X, Y, Z0, zdir='z', offset=-0.5)
ax.contour(X, Y, Z1, zdir='z', offset=-0.5)
ax.contour(X, Y, Z2, zdir='z', offset=-0.5)

ax.set_zlim(-0.5, 0.31)

plt.show()

结果图是这样的:

contours3d

如何让其他两个3D轮廓显示得很好?

1 个答案:

答案 0 :(得分:1)

这个问题没有一般解决方案。 Matplotlib无法决定在前面显示一个对象的一部分而不是另一部分。参见例如FAQ或其他问题,例如How to obscure a line behind a surface plot in matplotlib?

如果需要,当然可以将对象分成几个部分。但是,这里添加功能似乎已足够。

surf1 = ax.plot_surface(X, Y, Z0+Z1+Z2, cmap=plt.cm.coolwarm, 
                                        linewidth=0, antialiased=False)
ax.contour(X, Y, Z0+Z1+Z2, zdir='z', offset=-0.5)

enter image description here

相关问题