如何在Matplotlib中以3D绘制3个轮廓 [英] How do I plot 3 contours in 3D in matplotlib
问题描述
我有3个由以下内容生成的轮廓:
import numpy as np
import matplotlib.pyplot as从mpl_toolkits.mplot3d import axes3D plt
从scipy导入统计
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):
返回(stats.multivariate_normal.pdf((arg1,arg2),mean0,cov0))
def pdf1(arg1,arg2):
返回(stats.multivariate_normal。 pdf((arg1,arg2),mean1,cov1))
def pdf2(arg1,arg2):
return(stats.multivariate_normal.pdf((arg1,arg2),mean2,cov2))
对于范围(0,len(x))中的i:
对于范围(0,len(y))中的j:
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()
在视觉上,其绘制如下:
我希望将所有这些都绘制为3D图,但是当我尝试使用以下方式绘制时:
fig = plt.figure()
ax = fig.add_subplot(1,1,1,projection ='3d')
#每个轮廓的3D图。
surf1 = ax.plot_surface(X,Y,Z0,cmap = cm.coolwarm,线宽= 0,抗锯齿= 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。等高线(X,Y,Z0,zdir ='z',偏移= -0.5)
ax.contour(X,Y,Z1,zdir ='z',偏移= -0.5)
ax。等高线(X,Y,Z2,zdir ='z',offset = -0.5)
ax.set_zlim(-0.5,0.31)
plt.show()
结果图是这样的:
< a href = https://i.stack.imgur.com/rXJUi.png rel = nofollow noreferrer>
如何使其他两个3D轮廓很好地显示?
没有通用的解决方案。 Matplotlib无法决定将对象的一部分显示在前面而不是对象的另一部分。参见例如
I have 3 contours, generated by the following:
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()
Which, visually, is plotted as the following:
I am wishing to plot all of these in a 3D plot, but when I try do so with:
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()
The resulting graph is this:
How can I get the other two 3D contours to show nicely?
There is no general solution to this problem. Matplotlib cannot decide to show part of an object more in front than another part of it. See e.g. the FAQ, or other questions, like How to obscure a line behind a surface plot in matplotlib?
One may of course split up the object in several parts if necessary. Here, however, it seems sufficient to add the functions up.
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)
这篇关于如何在Matplotlib中以3D绘制3个轮廓的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!