在Vispy中创建matplotlib样式的3d散点图z轴

时间:2019-01-15 21:59:32

标签: python matplotlib point-clouds lidar vispy

我正在对极高密度的激光雷达点云(1M点+)进行博士研究,并且在将这些文件绘制到3D散点图上时确实遇到困难。 Matplotlib尚未针对大型数据集进行优化,因此,我尝试使用Vispy来实现这一点。现在,我在尝试启动并运行散点图样式的绘图时遇到了真正的麻烦,因此我可以开始构建管道。

我正在追求这样的事情:  matplotlib 3D scattergraph

使用Vispy,我发现很难应用z轴,并且在查找文档的哪一部分可以帮助我方面遇到困难。这是我的代码:

"""
This example demonstrates the use of the SurfacePlot visual.
"""

import sys
import numpy as np

from vispy import app, scene
from vispy.util.filter import gaussian_filter


canvas = scene.SceneCanvas(keys='interactive', bgcolor='w')
view = canvas.central_widget.add_view()
view.camera = scene.TurntableCamera(up='z', fov=60)

# Simple surface plot example
# x, y values are not specified, so assumed to be 0:50
z = np.random.normal(size=(250, 250), scale=200)
z[100, 100] += 50000
z = gaussian_filter(z, (10, 10))
print("This is z {0}".format(z))
p1 = scene.visuals.SurfacePlot(z=z, color=(0.3, 0.3, 1, 1))
p1.transform = scene.transforms.MatrixTransform()
p1.transform.scale([1/249., 1/249., 1/249.])
p1.transform.translate([-0.5, -0.5, 0])

view.add(p1)

# p1._update_data()  # cheating.
# cf = scene.filters.ZColormapFilter('fire', zrange=(z.max(), z.min()))
# p1.attach(cf)


xax = scene.Axis(pos=[[-0.5, -0.5], [0.5, -0.5]], tick_direction=(0, -1),
                 font_size=16, axis_color='k', tick_color='k', text_color='k',
                 parent=view.scene)
xax.transform = scene.STTransform(translate=(0, 0, -0.2))

yax = scene.Axis(pos=[[-0.5, -0.5], [-0.5, 0.5]], tick_direction=(-1, 0),
                 font_size=16, axis_color='k', tick_color='k', text_color='k',
                 parent=view.scene)
yax.transform = scene.STTransform(translate=(0, 0, -0.2))

zax = scene.Axis(pos=[[1.0, 1.0], [-1.0, 1.0]], tick_direction=(-1, 0),
                 font_size=16, axis_color='k', tick_color='k', text_color='k',
                 parent=view.scene)
zax.transform = scene.STTransform(translate=(0.0, 0.0, -0.2))


# Add a 3D axis to keep us oriented
axis = scene.visuals.XYZAxis(parent=view.scene)

if __name__ == '__main__':
    canvas.show()
    if sys.flags.interactive == 0:
        app.run()

它使图形如下所示:

vispy_example_plot

您可以在上图中看到我的问题。我想将第三个轴定位为垂直于其他轴,并且将网格定为与绘图的壁垂直,这样数据就更加定义了。

不幸的是,使用matplotlib进行子采样和其他技巧来显示数据对我来说并不是最佳选择,因为我必须显示原始数据,而不是显示子集。当然,如果有其他我可以用来显示数据的策略,那我就会不知所措。

预先感谢,希望有人可以提供帮助

1 个答案:

答案 0 :(得分:0)

在研究相机深度图像和远场雷达数据时,我遇到了同样的问题。由于vispy仅支持2d轴,因此可以在创建后旋转z轴。这里是您的代码的略微修改版本:

import sys
import numpy as np
from vispy import app, scene
from vispy.util.filter import gaussian_filter

canvas = scene.SceneCanvas(keys='interactive', bgcolor='w')
view = canvas.central_widget.add_view()
view.camera = scene.TurntableCamera(up='z', fov=60)

z = np.random.normal(size=(250, 250), scale=200)
z[100, 100] += 50000
z = gaussian_filter(z, (10, 10))

p1 = scene.visuals.SurfacePlot(z=z, color=(0.3, 0.3, 1, 1))
p1.transform = scene.transforms.MatrixTransform()
p1.transform.scale([1/249., 1/249., 1/249.])
view.add(p1)

xax = scene.Axis(pos=[[0, 0], [1, 0]], tick_direction=(0, -1), axis_color='r', tick_color='r', text_color='r', font_size=16, parent=view.scene)
yax = scene.Axis(pos=[[0, 0], [0, 1]], tick_direction=(-1, 0), axis_color='g', tick_color='g', text_color='g', font_size=16, parent=view.scene)

zax = scene.Axis(pos=[[0, 0], [-1, 0]], tick_direction=(0, -1), axis_color='b', tick_color='b', text_color='b', font_size=16, parent=view.scene)
zax.transform = scene.transforms.MatrixTransform()  # its acutally an inverted xaxis
zax.transform.rotate(90, (0, 1, 0))  # rotate cw around yaxis
zax.transform.rotate(-45, (0, 0, 1))  # tick direction towards (-1,-1)

if __name__ == '__main__':
    canvas.show()
    if sys.flags.interactive == 0:
        app.run()

致谢