opengl读取网格数据绘制三维物体_交互式三维绘图库(WxGL)速览

WxGL是一个基于PyOpenGL的三维数据可视化库,以wx为显示后端,提供Matplotlib风格的交互式应用模式,同时,也可以和wxPython无缝结合,在wx的窗体上绘制三维模型。WxGL提供了一套简洁易用、对用户友好的API,将OpenGL的复杂概念全部封装起来,使得用户可以专注于数据的处理,而无需将更多精力用在3D显示方面。可以说,WxGL是为实现数据快速可视化而诞生的。 WxGL遵循MIT开源软件许可协议,任何人都可以使用、复制和修改本软件,甚至出版发行、再授权以及贩售本软件。唯一的限制是,必须附有MIT授权协议。WxGL的源码和本文的示例代码、资源, 都可以从 https://github.com/xufive/wxgl 下载。 从V0.6.2开始,WxGL新增了交互式绘图子模块wxplot,提供类似Matplotlib风格的2D/3D绘图函数。如果熟悉NumPy和Matplotlib的话,只需要几分钟时间就可以学会使用WxGL的交互式绘图。 和其他的Python模块一样,WxGL模块可以直接使用pip命令安装。
pip install wxgl
如何使用WxGL进行数据可视化

WxGL与Matplotlib的使用网格类似,使用WxGL绘制正弦曲线小菜一碟:

>>> import numpy as np
>>> import wxgl.wxplot as plt
>>> x = np.linspace(0, 2*np.pi, 361)
>>> y = np.sin(x) * 3
>>> plt.plot(x, y)
>>> plt.show()

opengl读取网格数据绘制三维物体_交互式三维绘图库(WxGL)速览_第1张图片

与Matplotlib类似, WxGL也需要在画布上进行绘图。默认的,WxGL使用3D的画布,对于二维的数据,可手动设计为2D模式:
>>> theta = np.linspace(0, 2*np.pi, 361)
>>> x = 3 * np.cos(theta)
>>> y = 3 * np.sin(theta)
>>> fig = plt.figure(mode='2D')    # 创建2D画布
>>> plt.plot(x, y)
>>> plt.show()

opengl读取网格数据绘制三维物体_交互式三维绘图库(WxGL)速览_第2张图片

plt.figure创建画布时,还支持如下参数:

>>> print(plt.figure.__doc__)
    新建画布
    Useage: figure(*args, **kwds)
    ----------------------------------------------------
    size        - 画布分辨率,默认800x600
    kwds        - 关键字参数
                    head        - 定义方向:'x+'|'y+'|'z+'
                    zoom        - 视口缩放因子
                    mode        - 2D/3D模式
                    elevation   - 仰角
                    azimuth     - 方位角
                    style       - 配色方案,'black'|'white'|'gray'|'blue'

WxGL提供了大量的内置函数来绘制标准的图形,如绘制六面体:

>>> plt.cube((0,0,0), 3, 'cyan')
>>> plt.show()

opengl读取网格数据绘制三维物体_交互式三维绘图库(WxGL)速览_第3张图片

这个六面体只有线条,并没有填充面。在WxGL大多数函数中,都提供了显示模式参数,支持4种显示模式:
  • FCBC:前后面填充颜色

    opengl读取网格数据绘制三维物体_交互式三维绘图库(WxGL)速览_第4张图片

  • FLBL:前后面显示线条opengl读取网格数据绘制三维物体_交互式三维绘图库(WxGL)速览_第5张图片
  • FCBL:前面填充颜色,后面显示线条

    opengl读取网格数据绘制三维物体_交互式三维绘图库(WxGL)速览_第6张图片

  • FLBC:前面显示线条,后面填充颜色

    opengl读取网格数据绘制三维物体_交互式三维绘图库(WxGL)速览_第7张图片

此外,还支持如下绘图函数:
  • plt.mesh:绘制曲面

  • plt.pipe:绘制圆管

  • plt.sphere:绘制球体

  • plt.cylinder:绘制圆柱体

  • plt.cone:绘制圆锥体

  • plt.capsule:绘制三维等值面

  • plt.flow:绘制流体

秉承代码即文档的思想,查看WxGL的文档非常简单,如果查看cube的文件,只需要:

__doc__)除了绘制基本的图形之外,WxGL还提供了一系列的辅助功能:
  • plt.title:绘制标题

  • plt.text:绘制文本

  • plt.colorbar:绘制ColorBar

  • plt.ticks:绘制网格和刻度

使用上面的函数组合在一起,就可以绘制出复杂的三维图形:
>>> plt.cube((0,0,0), 3, 'cyan') # 绘制六面体,cyan是颜色,十六进制表示为#00FFFF
>>> plt.sphere((0,0,0), 1.5, 'orange') # 绘制球
>>> plt.cylinder((0,0,-2), (0,0,2), 0.5, 'green') # 绘制圆柱
>>> plt.cone((0,-2,0), (0,2,0), 0.5, 'purple') # 绘制圆锥,purple是颜色,十六进制表示为#F020F0
>>> plt.title('六面体、圆锥、圆柱和球的组合') # 绘制标题
>>> plt.text('这是锥尖', size=40, pos=(0,2,0), align='left') # 绘制文本
>>> plt.show()
opengl读取网格数据绘制三维物体_交互式三维绘图库(WxGL)速览_第8张图片

对于三维数据的可视化,ColorBar是非常常用的辅助功能:

>>> x, y = np.mgrid[-1:1:20j,-1:1:20j]
>>> z = x*x + y*y
>>> plt.mesh(x, y, z, mode='FLBL', cmap='hsv') # 其实,mesh()函数默认使用的颜色映射表就是hsv
>>> plt.colorbar((z.min(), z.max()), 'hsv') # colorbar()的颜色映射表要和要和绘图函数一致
>>> plt.show()
opengl读取网格数据绘制三维物体_交互式三维绘图库(WxGL)速览_第9张图片

plt.show,不仅仅是显示那么简单,使用它,可以轻而易举的实现动画效果:

>>> theta = np.linspace(np.pi/12, 11*np.pi/12, 21) # 在15°到165°之间生成21个点
>>> y = np.cos(theta) * 10 # 弧线上点的y坐标
>>> z = np.sin(theta) * 10 # 弧线上点的y坐标
>>> x = np.array([i%2-0.5 for i in range(21)]) # 弧线上点的x坐标,上下交替
>>> vs = np.stack((x,y,z), axis=1) # 组合成顶点坐标,此时vs的shape是(21,3)
>>> vs = np.vstack((np.array([0,0,0]), vs)) # 将原点加到vs的首位,此时vs的shape是(22,3)
>>> cs = plt.cmap(vs[:,0], 'wind') # 将x的值映射为颜色,使用wind映射表
>>> plt.surface(vs, color=cs, method='F', mode='FLBC')
>>> plt.show(rotation='h+')

纹理,在OpenGL中的应用比较困难,经过WxGL的封装,纹理简单到只需要提供图片路径即可:
>>> vs = np.array([
    [1,-1,1], [1,-1,-1], [1,1,-1], [1,1,1],
    [-1,1,1], [-1,1,-1], [-1,-1,-1], [-1,-1,1], 
    [-1,-1,1], [-1,-1,-1], [1,-1,-1], [1,-1,1], 
    [1,1,1], [1,1,-1], [-1,1,-1], [-1,1,1]
])
>>> plt.surface(vs, texture=r'example\res\girl.jpg', alpha=False)
>>> plt.show(rotation='h+')
WxGL尝试使用flow()函数展示粒子系统的部分功能,并使用了可编程管线技术(但并未开放接口)。下面的代码,前半部分是地形绘制,然后在4500米~5000米的高度上随机生成了500个雪花初始点,并使用u/v/w分量形式指定雪花的降落速度,最后使用flow()函数绘制出雪花飘落的样子。
>>> data = np.load(=r'example\res\landforms.npz')
>>> lon = data['lon']
>>> lat = data['lat']
>>> height = data['height']
>>> landforms = data['landforms']
>>> lons, lats = np.meshgrid(lon, lat) # 生成经纬度网格
>>> plt.mesh(lons, lats, height/50000, color=landforms/255)
>>> x = 116.65 + np.random.random(500) * (117.65-116.65) # 随机生成500个雪花点x坐标
>>> y = 36.25 + np.random.random(500) * (37.00-36.25) # 随机生成500个雪花点y坐标
>>> z = 4500 + np.random.random(500) * 500 # 随机生成500个雪花点z坐标(4500米~5000米)
>>> vs = np.stack((x,y,z/10000), axis=1) # 合并成500个顶点坐标
>>> u = np.sin(3*x) # 雪花在东西方的速度分量
>>> v = np.cos(4*y) # 雪花在南北方的速度分量
>>> w = -10 - np.random.random(500)  # 雪花垂直方向的速度分量
>>> plt.flow(vs, u/100, v/100, w/100, length=4, frames=30, interval=50, color=(0.8,0.8,0.8), actor='point', size=3)
>>> plt.ticks(zlabel_format=lambda z:'%0.1fkm'%(z*10))
>>> plt.show()

怎么样,功能是不是很强大,感兴趣的小伙伴们快来体验一下吧。若想深入学习WxGL的使用,可参考作者的博文《十分钟玩转3D绘图:WxGL完全手册》(https://blog.csdn.net/xufive/article/details/108958992)。

opengl读取网格数据绘制三维物体_交互式三维绘图库(WxGL)速览_第10张图片

你可能感兴趣的:(opengl读取网格数据绘制三维物体_交互式三维绘图库(WxGL)速览)