当前位置: 首页 > 面试题库 >

仅使用matplotlib绘制3D图形的一部分

轩辕弘雅
2023-03-14
问题内容

使用python的matplotlib绘制3d图形时出现问题。使用以下python函数,我得到了这个图:

图1

在这里XY有孔栅格和ZZ_的功能XYC代表表面颜色。

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之间的部分。

我想要的,用gnu​​plot绘制的是这样的:

图2

我尝试了ax.set_zlim3dax.set_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_surface。Matplotlib具有2d渲染器,因此3d可视化有点麻烦。这意味着对于复杂的重叠曲面,您经常会遇到渲染伪影(特别是两个简单连接的曲面彼此之间完全在后或完全在前面)。

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

from matplotlib.cm import get_cmap

# create a color mapping manually
Elim = 1  #threshold
cmap = get_cmap('viridis')
colors_top = cmap((E + Elim)/2/Elim) # listed colormap that maps E from [-Elim, Elim] to [0.0, 1.0] for color mapping
colors_bott = cmap((-E + Elim)/2/Elim) # same for -E branch
colors_top[E > Elim, -1] = 0 # set outlying faces to be invisible (100% transparent)
colors_bott[-E < -Elim, -1] = 0

# in nature you would instead have something like this:
#zmin,zmax = -1,1 # where to cut the _single_ input surface (x,y,z)
#cmap = get_cmap('viridis')
#colors = cmap((z - zmin)/(zmax - zmin))
#colors[(z < zmin) | (z > zmax), -1] = 0
# then plot_surface(x, y, z, facecolors=colors, ...)

# or for your specific case where you have X, Y, Z and C:
#colors = get_cmap('viridis')(C)
#colors[(z < zmin) | (z > zmax), -1] = 0
# then plot_surface(x, y, z, facecolors=colors, ...)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# pass the mapped colours as the facecolors keyword arg
s1 = ax.plot_surface(kx, ky, E, facecolors=colors_top, rstride=1, cstride=1)
s2 = ax.plot_surface(kx, ky, -E, facecolors=colors_bott, rstride=1, cstride=1)
# but now we need to manually hide the invisible part of the surface:
ax.set_zlim(-Elim, Elim)

plt.show()

这是输出:
更新版本,没有渲染神器

请注意,它看起来与早期的数字有些不同,因为之间相隔了3年,并且当前版本的matplotlib(3.0.2)具有非常不同(且更漂亮)的默认样式。尤其是,现在曲面图中的边缘是透明的。但是要点是渲染错误已消失,如果您开始在交互式绘图中旋转曲面,这是显而易见的。



 类似资料:
  • 主要内容:第一个三维绘图程序,3D散点图,3D等高线图,3D线框图,3D曲面图最初开发的 Matplotlib,仅支持绘制 2d 图形,后来随着版本的不断更新, Matplotlib 在二维绘图的基础上,构建了一部分较为实用的 3D 绘图程序包,比如 ,通过调用该程序包一些接口可以绘制 3D散点图、3D曲面图、3D线框图等 mpl_toolkits 是 Matplotlib 的绘图工具包。 第一个三维绘图程序 下面编写第一个三维绘图程序。 首先创建一个三维绘图区域, plt

  • 问题内容: 有没有办法直接使用字典中的数据来绘制条形图? 我的字典看起来像这样: 我期待 工作,但事实并非如此。 这是错误: 问题答案: 您可以通过首先绘制条形图然后设置适当的刻度来分两行进行: 请注意,倒数第二行应在python3中读取,因为它会返回一个生成器,而matplotlib无法直接使用该生成器。

  • 问题内容: 我正在尝试使用该模块制作动画,但是我的代码仅产生一帧,然后停止。似乎没有意识到需要更新什么。您能帮我解决问题吗? 问题答案: 您需要保留对动画对象的引用,否则它会被垃圾收集并且计时器消失。 将硬引用动画附加到基础对象存在一个未解决的问题。 由于写的,你的代码以及只绘制一个点,这将是不可见的,我改变了它有点吸取 多达 当前索引

  • 本文向大家介绍Three.js的使用及绘制基础3D图形详解,包括了Three.js的使用及绘制基础3D图形详解的使用技巧和注意事项,需要的朋友参考一下 一、 前言 Three.js 是一款 webGL(3D绘图标准,在此不赘述)引擎,可以运行于所有支持 webGL 的浏览器。Three.js 封装了 webGL 底层的 API ,为我们提供了高级的开发接口,可以使用简单的代码去实现 3D 渲染。(

  • numpy.histogram()函数将输入数组和作为两个参数。 bin数组中的连续元素用作每个bin的边界。 Matplotlib 可以将直方图的数字表示转换为图形。 pyplot子模块的plt()函数将包含数据和数组的数组作为参数,并转换为直方图。

  • 问题内容: 我使用以下代码处理了一个简单的3d条形图: 认为这只是一个测试,到目前为止,一切似乎都还很清楚。我只是想知道如何以堆叠的方式绘制这9个条形图的每一个,以便例如将每个条形图分成4个部分,组成整个条形图。 基本上,我想以此处的示例方式执行此操作。 但是,我希望有2个堆栈,而不是2个堆栈。有什么想法可以从我现在的角度出发吗?每个提示将不胜感激。 谢谢! 编辑:如果我想实现每个堆叠的酒吧给定的