Python matplotlib Axes3D中的mayavi 3d对象

Python matplotlib Axes3D中的mayavi 3d对象,python,matplotlib,mayavi,mplot3d,Python,Matplotlib,Mayavi,Mplot3d,有时,我发现自己对matplotlib的mplot3d中缺少某些渲染功能感到沮丧。在大多数情况下,我确实发现我可以在mayavi中得到我想要的东西,但matplotlib 3d轴仍然更可取,如果只是为了美观,比如标签和与其他图形的视觉一致性 我这里的问题是关于一个明显的问题:是否可以在mayavi中绘制一些没有轴的3d对象(曲面或3d散点图或任何东西),导出该图像,然后将其放置在具有正确大小、方向、坐标投影等的matplotlib Axes3D中。?谁能想出一个实现这一目标所需的大纲,或者甚至提

有时,我发现自己对matplotlib的mplot3d中缺少某些渲染功能感到沮丧。在大多数情况下,我确实发现我可以在mayavi中得到我想要的东西,但matplotlib 3d轴仍然更可取,如果只是为了美观,比如标签和与其他图形的视觉一致性

我这里的问题是关于一个明显的问题:是否可以在mayavi中绘制一些没有轴的3d对象(曲面或3d散点图或任何东西),导出该图像,然后将其放置在具有正确大小、方向、坐标投影等的matplotlib Axes3D中。?谁能想出一个实现这一目标所需的大纲,或者甚至提供一个框架解决方案

不久前,我对它进行了修改,发现导出一个透明背景的mayavi图形并将其放置在一个空的matplotlib Axes3D(带有记号、标签等)中并没有遇到任何问题,但我在使mayavi和matplotlib的相机配置相匹配方面没有取得多大进展。在这两种环境中,简单地将方位角、仰角和距离这三个常用参数设置为相等并没有起到作用;大概需要考虑透视(或其他)变换来渲染整个场景,而我在这方面相当无知

这似乎很有用:

我使用PGFPlots手册的和“支持外部三维图形”部分为Mayavi->PGFPlots提供了概念验证解决方案

程序:

  • 使用Mayavi运行修改后的
    mlab_3D_to_2D.py
    ,生成
    img.png
    。将四个随机点打印到控制台,将它们复制到剪贴板。注:图形尺寸和分辨率硬编码到脚本中,应针对不同的图像尺寸编辑或自动提取
  • 将点粘贴到
    mlab_pgf.tex
  • mlab_pgf.tex
    上运行LaTeX
  • 结果:

    将mlab_3D_修改为_2D.py:

    #将mlab_3D_从https://docs.enthought.com/mayavi/mayavi/auto/example_mlab_3D_to_2D.html
    #版权声明原件:
    #作者:S.克里斯·科尔伯特
    #版权所有(c)2009,S.Chris Colbert
    #许可证:BSD样式
    来自未来导入打印功能
    #之所以在这里导入,是因为我们需要确保matplotlib使用
    #wx后端和在主块之外有常规代码是PyTab的禁忌。
    #首先需要导入它,以便matplotlib可以强制
    #它需要的Wx版本。
    导入matplotlib
    #matplotlib.use('WXAgg')
    将pylab作为pl导入
    将numpy作为np导入
    来自mayavi import mlab
    从mayavi.core.ui.mayavi_场景导入mayavi场景
    def get_world_to_view_矩阵(mlab_场景):
    “”“返回4x4矩阵,该矩阵是modelview转换和
    透视变换。将mlab场景对象作为输入。”“”
    如果不存在(mlab_场景,MayaviScene):
    raise TypeError('参数必须是MayaviScene'的实例)
    #VTK方法需要纵横比以及近剪裁平面和远剪裁平面
    #以返回正确的变换。所以我们查询当前场景
    #对象以获取所需的参数。
    场景大小=元组(mlab\u scene.get\u size())
    clip\u range=mlab\u scene.camera.clipping\u range
    纵横比=浮点(场景大小[0])/float(场景大小[1])
    #这实际上只是得到一个vtk矩阵对象,我们还不能用它做任何事情
    vtk_comb_trans_mat=mlab_scene.camera.get_composite_projection_transform_mat(
    纵横比、剪辑范围[0],剪辑范围[1])
    #将vtk mat作为numpy阵列获取
    np_comb_trans_mat=vtk_comb_trans_mat.to_array()
    返回np_梳_trans_垫
    def get_view_to_display_矩阵(mlab_场景):
    “”“此函数返回一个4x4矩阵,该矩阵将
    视图坐标以显示坐标。假定视图
    占据整个窗口,并且窗口的原点位于
    左上角“”
    如果不是(isinstance(mlab_场景,MayaviScene)):
    raise TypeError('参数必须是MayaviScene'的实例)
    #这将获取窗口的客户端大小
    x、 y=元组(mlab_场景。获取_大小())
    标准化的视图坐标在空间的中间有原点。
    #所以,我们需要根据显示窗口的宽度和高度进行缩放并移动
    #半宽半高。矩阵实现了这一点。
    视图到显示材料=np.数组([[x/2.0,0,0,x/2.0],
    [0.,-y/2.0,0.,y/2.0],
    [   0.,      0.,   1.,      0.],
    [   0.,      0.,   0.,      1.]])
    将视图返回到显示垫
    def将_变换_应用于_点(点、变换垫):
    “”“将4x4变换矩阵应用于的函数”
    齐次点。点阵列的形状应为Nx4“”
    如果不是横截面形状==(4,4):
    raise VALUERROR('变换矩阵必须为4x4')
    如果不是点。形状[1]==4:
    raise VALUEMERROR('点阵列必须具有形状Nx4')
    返回np.dot(trans_mat,points.T).T
    def test_surf():
    “”“在有规则间隔的坐标(如MayaVi)上测试冲浪。”“”
    定义f(x,y):
    sin,cos=np.sin,np.cos
    返回sin(x+y)+sin(2*x-y)+cos(3*x+4*y)
    x、 y=np.mgrid[-7:7.05:0.1,-5:5.05:0.05]
    z=f(x,y)
    s=mlab.surf(x,y,z)
    #cs=等高线(x,y,f,等高线z=0)
    返回x,y,z,s
    如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
    f=mlab.图()
    f、 scene.parallel_projection=True
    N=4
    #x,y,z,m=测试网格()
    x、 y,z,s=测试
    mlab.移动(向前=2.0)
    #现在我们要创建一个由点组成的nx4数组
    #添加第四列“一”表示中的世界点
    #齐次坐标
    W=np.one(x.flatte().shape)
    hmgns_world_coords=np。