如何在Matplotlib中以3D绘制3个轮廓 [英] How do I plot 3 contours in 3D in matplotlib

查看:154
本文介绍了如何在Matplotlib中以3D绘制3个轮廓的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆