2025年4月15日 星期二 乙巳(蛇)年 正月十六 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

Python Vispy库:高性能科学可视化工具

时间:08-08来源:作者:点击数:41

Vispy是一个用于科学可视化的高性能Python库,特别适用于需要实时交互和大规模数据处理的应用。它基于OpenGL构建,提供了简洁的API,方便开发者创建复杂的可视化应用。Vispy支持2D和3D绘图,能够处理从简单图形到高级图形的大量任务。本文将详细介绍Vispy库的安装、主要功能、基本操作、高级功能及其实践应用,并提供丰富的示例代码。

安装

Vispy可以通过pip进行安装。确保Python环境已激活,然后在终端或命令提示符中运行以下命令:

  • pip install vispy

Vispy依赖于OpenGL,因此需要确保你的系统已安装OpenGL。

如果你使用的是Linux或macOS,可以通过包管理器安装:

  • # macOS
  • brew install --cask xquartz
  • # Ubuntu
  • sudo apt-get install libgl1-mesa-glx

对于Windows用户,可以从OpenGL官网下载并安装。

主要功能

  1. 2D和3D绘图:支持创建2D和3D图形。
  2. 实时交互:支持鼠标、键盘等交互操作。
  3. 高性能渲染:基于OpenGL,能够高效处理大规模数据。
  4. 丰富的图形元素:支持点、线、面、体等多种图形元素。
  5. 集成多种后端:支持PyQt、PySide、GLFW等多种图形后端。

基本操作

创建简单的2D绘图

以下示例展示了如何使用Vispy创建一个简单的2D绘图:

  • import vispy.plot as vp
  • # 创建一个2D绘图
  • fig = vp.Fig(size=(800600), show=False)
  • scatter = fig[00].plot((012), (010), symbol='o', width=0)
  • fig.show(run=True)
创建简单的3D绘图

以下示例展示了如何使用Vispy创建一个简单的3D绘图:

  • import numpy as np
  • from vispy import scene
  • # 创建一个3D绘图
  • canvas = scene.SceneCanvas(keys='interactive', show=True)
  • view = canvas.central_widget.add_view()
  • # 生成随机3D数据
  • pos = np.random.normal(size=(100003), scale=0.2)
  • # 创建3D散点图
  • scatter = scene.visuals.Markers()
  • scatter.set_data(pos, edge_color=None, face_color=(1110.5), size=5)
  • view.add(scatter)
  • # 设置视角
  • view.camera = 'turntable'
  • canvas.app.run()
实时交互

Vispy支持鼠标和键盘等交互操作。以下示例展示了如何实现简单的鼠标交互:

  • from vispy import app, scene
  • canvas = scene.SceneCanvas(keys='interactive', show=True)
  • view = canvas.central_widget.add_view()
  • # 生成随机3D数据
  • pos = np.random.normal(size=(100003), scale=0.2)
  • # 创建3D散点图
  • scatter = scene.visuals.Markers()
  • scatter.set_data(pos, edge_color=None, face_color=(1110.5), size=5)
  • view.add(scatter)
  • # 设置视角
  • view.camera = 'turntable'
  • # 定义鼠标点击事件
  • @canvas.events.mouse_press.connect
  • def on_mouse_press(event):
  •     print(f"Mouse clicked at {event.pos}")
  • canvas.app.run()

高级功能

创建自定义视觉元素

Vispy允许用户创建自定义的视觉元素。

以下示例展示了如何创建一个自定义的视觉元素:

  • import numpy as np
  • from vispy import gloo, app
  • from vispy.visuals import Visual
  • from vispy.visuals.transforms import STTransform
  • from vispy.scene.visuals import create_visual_node
  • class CustomVisual(Visual):
  •     VERTEX_SHADER = """
  •     attribute vec2 a_position;
  •     void main() {
  •         gl_Position = vec4(a_position, 0.0, 1.0);
  •     }
  •     """
  •     FRAGMENT_SHADER = """
  •     void main() {
  •         gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  •     }
  •     """
  •     def __init__(self):
  •         super().__init__(self.VERTEX_SHADER, self.FRAGMENT_SHADER)
  •         self._vbo = gloo.VertexBuffer()
  •         self._program = gloo.Program(self.VERTEX_SHADER, self.FRAGMENT_SHADER)
  •     def set_data(self, data):
  •         self._vbo.set_data(data)
  •         self._program['a_position'] = self._vbo
  •     def _prepare_draw(self, view):
  •         pass
  •     def _prepare_transforms(self, view):
  •         pass
  • CustomNode = create_visual_node(CustomVisual)
  • canvas = scene.SceneCanvas(keys='interactive', show=True)
  • view = canvas.central_widget.add_view()
  • visual = CustomNode()
  • view.add(visual)
  • # 生成自定义数据
  • data = np.array([[-0.5, -0.5], [0.5, -0.5], [0.00.5]], dtype=np.float32)
  • visual.set_data(data)
  • canvas.app.run()
使用文本和图像

Vispy支持在图形中添加文本和图像。

以下示例展示了如何在图形中添加文本:

  • from vispy import app, scene
  • canvas = scene.SceneCanvas(keys='interactive', show=True)
  • view = canvas.central_widget.add_view()
  • # 生成随机3D数据
  • pos = np.random.normal(size=(100003), scale=0.2)
  • # 创建3D散点图
  • scatter = scene.visuals.Markers()
  • scatter.set_data(pos, edge_color=None, face_color=(1110.5), size=5)
  • view.add(scatter)
  • # 添加文本
  • text = scene.visuals.Text('Hello Vispy', color='white', anchor_x='center', anchor_y='center')
  • text.transform = STTransform(translate=(000))
  • view.add(text)
  • # 设置视角
  • view.camera = 'turntable'
  • canvas.app.run()

以下示例展示了如何在图形中添加图像:

  • import numpy as np
  • from vispy import app, scene
  • from vispy.io import load_data_file, read_png
  • canvas = scene.SceneCanvas(keys='interactive', show=True)
  • view = canvas.central_widget.add_view()
  • # 加载图像
  • image = read_png(load_data_file('mona_lisa/mona_lisa_sm.png'))
  • image_data = np.flipud(image)
  • # 创建图像视觉元素
  • image_visual = scene.visuals.Image(image_data, parent=view.scene)
  • # 设置视角
  • view.camera = 'panzoom'
  • canvas.app.run()
动态更新图形

Vispy允许动态更新图形,以实现实时数据可视化。

以下示例展示了如何动态更新2D散点图中的数据:

  • import numpy as np
  • from vispy import app, gloo, visuals
  • class Canvas(app.Canvas):
  •     def __init__(self):
  •         app.Canvas.__init__(self, keys='interactive')
  •         self.program = gloo.Program(visuals.MarkersVisual().vertex_shader, visuals.MarkersVisual().fragment_shader)
  •         self.data = np.random.rand(1002).astype(np.float32)
  •         self.program['a_position'] = self.data
  •         self.program['a_fg_color'] = np.ones((1004), dtype=np.float32)
  •         self.program['a_size'] = np.ones(100, dtype=np.float32) * 10
  •         gloo.set_state(clear_color='white', blend=True, blend_func=('src_alpha''one_minus_src_alpha'))
  •         self.timer = app.Timer('auto', self.on_timer)
  •         self.timer.start()
  •         self.show()
  •     def on_draw(self, event):
  •         gloo.clear()
  •         self.program.draw('points')
  •     def on_timer(self, event):
  •         self.data[:, 1] = np.random.rand(100)
  •         self.program['a_position'].set_data(self.data)
  •         self.update()
  • canvas = Canvas()
  • app.run()
交互式数据选择

Vispy支持用户与图形进行交互,例如选择和高亮数据点。

以下示例展示了如何实现交互式数据选择:

  • import numpy as np
  • from vispy import app, scene
  • class Canvas(app.Canvas):
  •     def __init__(self):
  •         app.Canvas.__init__(self, keys='interactive')
  •         self.unfreeze()
  •         self.view = self.central_widget.add_view()
  •         self.scatter = scene.visuals.Markers()
  •         self.view.add(self.scatter)
  •         self.data = np.random.rand(1002).astype(np.float32)
  •         self.scatter.set_data(self.data, face_color=(0011), size=5)
  •         self.view.camera = 'panzoom'
  •         self.freeze()
  •     def on_mouse_press(self, event):
  •         if event.button == 1:
  •             pos = event.pos
  •             tr = self.scatter.get_transform(map_to='canvas')
  •             trpos = tr.map(self.data)
  •             d = np.sqrt((trpos[:, 0] - pos[0]) ** 2 + (trpos[:, 1] - pos[1]) ** 2)
  •             idx = np.argmin(d)
  •             self.scatter.set_data(self.data, face_color=(0011), size=5)
  •             self.scatter.markers.set_data(self.data[idx:idx+1], face_color=(1001), size=10)
  •             self.update()
  • canvas = Canvas()
  • app.run()

实践应用

可视化分子结构

Vispy可以用于可视化科学数据,例如分子结构。

以下示例展示了如何可视化简单的分子结构:

  • import numpy as np
  • from vispy import scene
  • from vispy.visuals import Sphere, Tube
  • canvas = scene.SceneCanvas(keys='interactive', show=True)
  • view = canvas.central_widget.add_view()
  • # 创建分子结构数据
  • atoms = np.array([[000], [111], [-1, -1, -1]], dtype=np.float32)
  • bonds = np.array([[01], [12]], dtype=np.float32)
  • # 创建原子视觉元素
  • spheres = Sphere(radius=0.1, method='latitude', parent=view.scene)
  • spheres.transform = scene.transforms.MatrixTransform()
  • spheres.transform.translate(atoms)
  • # 创建键视觉元素
  • for bond in bonds:
  •     tube = Tube(points=atoms[bond], radius=0.05, method='cylinder', parent=view.scene)
  • # 设置视角
  • view.camera = 'turntable'
  • canvas.app.run()
机器学习结果可视化

以下示例展示了如何使用Vispy可视化机器学习模型的训练结果,例如损失和准确率的变化:

  • import numpy as np
  • from vispy import app, gloo
  • vertex_shader = """
  • uniform mat4 u_transform;
  • attribute vec2 a_position;
  • void main() {
  •     gl_Position = u_transform * vec4(a_position, 0.0, 1.0);
  • }
  • """
  • fragment_shader = """
  • void main() {
  •     gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
  • }
  • """
  • class Canvas(app.Canvas):
  •     def __init__(self):
  •         app.Canvas.__init__(self, keys='interactive')
  •         self.program = gloo.Program(vertex_shader, fragment_shader)
  •         self.data = np.zeros((1002), dtype=np.float32)
  •         self.program['a_position'] = self.data
  •         self.program['u_transform'] = np.eye(4, dtype=np.float32)
  •         self.show()
  •     def on_draw(self, event):
  •         gloo.clear()
  •         self.program.draw('line_strip')
  •     def update_data(self, new_data):
  •         self.data[:, 1] = new_data
  •         self.program['a_position'].set_data(self.data)
  •         self.update()
  • canvas = Canvas()
  • canvas.update_data(np.random.rand(100))
  • app.run()
热力图可视化

Vispy支持绘制热力图,可以用于显示二维数据的密度或强度分布。

以下示例展示了如何使用Vispy绘制热力图:

  • import numpy as np
  • from vispy import scene, color
  • canvas = scene.SceneCanvas(keys='interactive', show=True)
  • view = canvas.central_widget.add_view()
  • # 生成二维数据
  • data = np.random.random((100100))
  • # 创建热力图视觉元素
  • heatmap = scene.visuals.Image(data, cmap='viridis', clim=(01), parent=view.scene)
  • # 设置视角
  • view.camera = 'panzoom'
  • canvas.app.run()

总结

Vispy库为Python开发者提供了一个功能强大且灵活的高性能科学可视化工具。通过其简洁的API和丰富的功能,用户可以轻松地创建各种复杂的可视化应用,包括实时数据流、3D模型、分子结构、机器学习结果和热力图的可视化。本文详细介绍了Vispy库的安装、主要功能、基本操作、高级功能及其实践应用,并提供了丰富的示例代码。希望在实际项目中能够充分利用Vispy库,提高数据可视化的效率和效果。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐