Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用matplotlib仅打印三维地物的一部分_Python_Matplotlib_Plot - Fatal编程技术网

Python 使用matplotlib仅打印三维地物的一部分

Python 使用matplotlib仅打印三维地物的一部分,python,matplotlib,plot,Python,Matplotlib,Plot,我在使用python的matplotlib绘制3d图形时遇到了一个问题。使用下面的python函数,我得到了这个图: 在这里,X,Y是网状网格,Z和Z是X和Y的函数C表示表面颜色 import numpy as np from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm import matplotlib.pyplot as plt def plot(X, Y, Z, Z_, C): fig = plt.fi

我在使用python的matplotlib绘制3d图形时遇到了一个问题。使用下面的python函数,我得到了这个图:

在这里,
X
Y
是网状网格,
Z
Z
X
Y
的函数
C
表示表面颜色

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

def plot(X, Y, Z, Z_, C):
   fig = plt.figure()
   ax = fig.gca(projection='3d')
   surf = ax.plot_surface(
           X, Y, Z, rstride=1, cstride=1,
           facecolors=cm.jet(C),
           linewidth=0, antialiased=False, shade=False)
   surf_ = ax.plot_surface(
           X, Y, Z_, rstride=1, cstride=1,
           facecolors=cm.jet(C),
          linewidth=0, antialiased=False, shade=False)                    
   ax.view_init(elev=7,azim=45)
   plt.show()
但是现在我想水平切割这个图形,只剩下z在-1和2之间的部分

我想要用gnuplot绘制的是:


我试过
ax.set\u zlim3d
ax.set\u zlim
,但它们都没有给我想要的数字。有人知道如何使用python吗?

你那里有漂亮的圆锥交点:)

应该通过将要忽略的
Z
数据设置为
NaN
来实现您的尝试。以石墨烯的紧密结合带结构为例:

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

# generate dummy data (graphene tight binding band structure)
kvec = np.linspace(-np.pi,np.pi,101)
kx,ky = np.meshgrid(kvec,kvec)
E = np.sqrt(1+4*np.cos(3*kx/2)*np.cos(np.sqrt(3)/2*ky) + 4*np.cos(np.sqrt(3)/2*ky)**2)

# plot full dataset
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(kx,ky,E,cmap='viridis',vmin=-E.max(),vmax=E.max(),rstride=1,cstride=1)
ax.plot_surface(kx,ky,-E,cmap='viridis',vmin=-E.max(),vmax=E.max(),rstride=1,cstride=1)



# focus on Dirac cones
Elim = 1  #threshold
E[E>Elim] = np.nan

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
#ax.plot_surface(kx2,ky2,E2,cmap='viridis',vmin=-Elim,vmax=Elim)
#ax.plot_surface(kx2,ky2,-E2,cmap='viridis',vmin=-Elim,vmax=Elim)
ax.plot_surface(kx,ky,E,cmap='viridis',rstride=1,cstride=1,vmin=-Elim,vmax=Elim)
ax.plot_surface(kx,ky,-E,cmap='viridis',rstride=1,cstride=1,vmin=-Elim,vmax=Elim)

plt.show()
结果如下所示:

不幸的是,第二种情况的渲染存在问题:在后一种情况下,数据的表面深度顺序混乱:背景中的圆锥体在前面的圆锥体之前渲染(在交互式绘图中,这更清晰)。问题是孔比实际数据多,并且数据没有连接,这会混淆
plot\u surface
的渲染器。Matplotlib有一个2d渲染器,所以3d可视化有点麻烦。这意味着,对于复杂的重叠曲面,您通常会得到渲染瑕疵(特别是,两个简单连接的曲面要么完全在后面,要么完全在前面)

我们可以通过做更多的工作来绕过渲染错误:不使用
nan
s将数据保存在单个曲面中,而是在我们不感兴趣的地方将曲面着色为不可见。由于我们正在绘制的曲面现在包括整个原始曲面,因此我们必须手动设置
zlim
,以便关注我们感兴趣的区域。对于上述示例:

从matplotlib.cm导入获取cmap
#手动创建颜色映射
Elim=1#阈值
cmap=get_cmap('viridis'))
颜色_top=cmap((E+Elim)/2/Elim)#列出的颜色映射,将E从[-Elim,Elim]映射到[0.0,1.0]进行颜色映射
颜色=cmap((-E+Elim)/2/Elim)#与-E分支相同
颜色顶部[E>Elim,-1]=0#将外围面设置为不可见(100%透明)
颜色\u bott[-E<-Elim,-1]=0
#实际上,你会有这样的东西:
#zmin,zmax=-1,1#切割_单输入曲面的位置(x,y,z)
#cmap=get_cmap('viridis'))
#颜色=cmap((z-zmin)/(zmax-zmin))
#颜色[(zzmax),-1]=0
#然后绘制曲面(x、y、z,面颜色=颜色,…)
#或者,对于具有X、Y、Z和C的特定情况:
#颜色=获取cmap(“绿色”)(C)
#颜色[(zzmax),-1]=0
#然后绘制曲面(x、y、z,面颜色=颜色,…)
图=plt.图()
ax=图添加_子图(111,投影='3d')
#将映射的颜色作为facecolors关键字arg传递
s1=最大绘图曲面(kx、ky、E、面颜色=顶部颜色,rstride=1,cstride=1)
s2=最大绘图曲面(kx,ky,-E,面颜色=颜色,rstride=1,cstride=1)
#但现在我们需要手动隐藏曲面的不可见部分:
ax.set_zlim(-Elim,Elim)
plt.show()
以下是输出:


请注意,它看起来与前面的图有点不同,因为三年过去了,当前版本的matplotlib(3.0.2)具有非常不同(而且更漂亮)的默认样式。特别是,边现在在曲面打印中是透明的。但主要的一点是,渲染错误消失了,如果在交互式绘图中开始旋转曲面,这一点很明显。

我的第二个最佳猜测是,
plot\u trisurf
也会产生此伪影(如果我将不必要的值设置为
NaN
),或者在阈值级别绘制丑陋的水平线(如果我只是将所需的值提取到新的向量中,没有任何
NaN
s)。@jjj是的,很简单。如果你只是想更改颜色,没有任何东西可以阻止你传递
vmin=F.min()、vmax=F.max()
或其他东西。如果你想在这些值之外隐藏曲面,你需要更改
E[E>Elim]=np.nan
到类似于
E[(是的,
np.nan
s做到了,谢谢!再次+1,但已经做到了:)@JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ(即100%透明),不接触其他颜色。(渲染错误的原因是使用
nan
s将提供显式不相交的曲面,并且单独的曲面彼此渲染错误。使用不可见面片愚弄渲染器,将这些部分作为一个大曲面处理,渲染正确。)我不认为这与你有什么关系,只是为了安全起见:我更新了答案,告诉你如何通过更多的工作绕过渲染错误。