matplotlib从起点出发(15)_Tutorial_15_blitting

0 位图传输技术与快速渲染

Blitting,即位图传输、块传输技术是栅格图形化中的标准技术。在Matplotlib的上下文中,该技术可用于(大幅度)提高交互式图形的性能。例如,动画和小部件模块在内部使用位图传输。在这里,我们将演示如何在这些类之外实现自己的blitting。

位图传输技术通过将所有不变的图形元素渲染到背景图像中来加速重复绘图。然后,对于每次绘图,只需要将不断变化的元素绘制到此背景上。例如,如果一个Axes的限制没有改变,我们可以渲染一次空轴,包括所有刻度和标签,然后只绘制变化的数据。

这种策略是:

  • 准备常量背景:
    • 绘制图形,但通过将所有要动画化的artists对象标记为动画来排除它们(参看Artist.set_animated);
    • 保存一份RBGA缓存的备份。
  • 渲染单个图像:
    • 还原RBGA缓冲区的副本;
    • 使用Axes.draw_artist/Figure.draw_artist重新绘制动画Artist;
    • 在屏幕上显示生成的图像。

此过程的一个结果是,你的动态artists始终绘制在静态artists之上。

并非所有的后端都支持传输。你可以通过以下的方式检查给定的画布是否支持这样做:FigureCanvasBase.supports_blit属性。

警告
此代码不适用于OSX后端(但适用于Mac上的其他GUI后端)。

1 最小示例

我们可以将FigureCanvasAgg方法copy_from_bboxrestore_region结合在artists上设置animated=True来实现一个使用位图传输来加速渲染的最小示例。

import matplotlib.pyplot as plt
import numpy as npx = np.linspace(0, 2 * np.pi, 100)fig, ax = plt.subplots()# animated=True 告诉 matplotlib 只在我们显式请求时才绘制
# 某个artist
(ln,) = ax.plot(x, np.sin(x), animated=True)# 确保窗口已经显示,但脚本继续运行
plt.show(block=False)# 停止欣赏空荡荡的窗口,确保至少渲染一次
#
# 我们需要在屏幕上完整绘制这个图形直到最终的大小
# 在我们继续之前 :
#  a) 我们有正确的大小和绘制的背景可以抓取
#  b) 我们可以渲染缓存,从而 ``ax.draw_artist`` 可以工作
# 所以我们旋转事件循环,让后端处理任何待处理的操作
plt.pause(0.1)# 获取整张图像的副本(所有fig.bbox中的内容)
bg = fig.canvas.copy_from_bbox(fig.bbox)
# 绘制动画artist, 这里使用了一个缓存渲染
ax.draw_artist(ln)
# 将结果显示到屏幕上,这将RGBA缓存更新从渲染器中推送到GUI框架上
# 从而让你能看得见它
fig.canvas.blit(fig.bbox)for j in range(100):# 将背景重置为画布状态,屏幕不变fig.canvas.restore_region(bg)# 更新artist, 画布状态和屏幕都保持不变ln.set_ydata(np.sin(x + (j / 100) * np.pi))# 重新渲染artist, 更新画布状态, 但不更新屏幕ax.draw_artist(ln)# 将图像复制到GUI状态,但屏幕可能尚未改变fig.canvas.blit(fig.bbox)# 刷新任何挂起的 GUI 事件,如果需要,重新绘制屏幕fig.canvas.flush_events()# 你可以旋转一个暂停在此如果你想要让整个过程降速# plt.pause(.1)

在这里插入图片描述

这个示例有效并显示了一个简单的动画,但是因为我们只抓取了一次背景,如果图形的像素大小发生变化(由于图形的大小或者dpi发生变化),背景就失效,并导致错误发生(但有时看起来会很酷,还有一个全局变量和相当多的样板,这表明我们应该将其包装在一个类中)。

2 基于类的示例

我们可以使用一个类来封装恢复背景、绘制artist,然后将结果传输到屏幕上的样板逻辑和状态。此外,每当发生完全重新绘制以正确处理调整大小时,我们使用"draw_event"回调来捕获新的背景。

class BlitManager:def __init__(self, canvas, animated_artists=()):"""Parameters----------canvas : FigureCanvasAggThe canvas to work with, this only works for subclasses of the Aggcanvas which have the `~FigureCanvasAgg.copy_from_bbox` and`~FigureCanvasAgg.restore_region` methods.animated_artists : Iterable[Artist]List of the artists to manage"""self.canvas = canvasself._bg = Noneself._artists = []for a in animated_artists:self.add_artist(a)# 在每次绘图上抓取背景self.cid = canvas.mpl_connect("draw_event", self.on_draw)def on_draw(self, event):"""Callback to register with 'draw_event'."""cv = self.canvasif event is not None:if event.canvas != cv:raise RuntimeErrorself._bg = cv.copy_from_bbox(cv.figure.bbox)self._draw_animated()def add_artist(self, art):"""Add an artist to be managed.Parameters----------art : ArtistThe artist to be added.  Will be set to 'animated' (justto be safe).  *art* must be in the figure associated withthe canvas this class is managing."""if art.figure != self.canvas.figure:raise RuntimeErrorart.set_animated(True)self._artists.append(art)def _draw_animated(self):"""Draw all of the animated artists."""fig = self.canvas.figurefor a in self._artists:fig.draw_artist(a)def update(self):"""Update the screen with animated artists."""cv = self.canvasfig = cv.figure# 如果错过了绘制事件,则什么也不画if self._bg is None:self.on_draw(None)else:# 还原背景cv.restore_region(self._bg)# 绘制所有的动画artistsself._draw_animated()# 更新GUI状态cv.blit(fig.bbox)# 让GUI事件循环处理所有它该干的事儿cv.flush_events()

以下是我们将如何使用我们的类。这是一个比第一种情况稍微复杂一些的例子,因为我们是学添加了一个文本框架计数器。

# 创建一个新的绘图
fig, ax = plt.subplots()
# 添加一条线
(ln,) = ax.plot(x, np.sin(x), animated=True)
# 添加帧序号
fr_number = ax.annotate("0",(0, 1),xycoords="axes fraction",xytext=(10, -10),textcoords="offset points",ha="left",va="top",animated=True,
)
bm = BlitManager(fig.canvas, [ln, fr_number])
# 确保你的窗口在屏幕上,绘图
plt.show(block=False)
plt.pause(.1)for j in range(100):#更新artistsln.set_ydata(np.sin(x + (j / 100) * np.pi))fr_number.set_text(f"frame: {j}")# 告诉位图传输管理器来更新bm.update()

在这里插入图片描述

此类不依赖于pyplot,适合嵌入到更大的GUI应用程序中。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/637701.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Drive Scope for Mac:硬盘健康监测分析工具

Drive Scope for Mac是一款专为Mac用户设计的硬盘健康监测与分析工具,致力于保障用户的数据安全。这款软件功能强大且操作简便,能够实时检测硬盘的各项指标,帮助用户及时发现并解决潜在问题。 Drive Scope for Mac 1.2.23注册激活版下载 Driv…

智慧化转型赋能园区创新:科技创新引领产业智慧化,打造高效发展新格局

在全球化和信息化浪潮的推动下,园区作为区域经济发展的重要引擎,正面临着前所未有的机遇与挑战。为应对这些挑战并把握机遇,园区需积极拥抱智慧化转型,通过科技创新引领产业智慧化,打造高效发展的新格局。本文将深入探…

设计模式之观察者模式(优先使用对象组合的原则)的C++实现

观察者模式又称订阅者发布者模式,本篇介绍主要是利用对象组合大于类继承的设计模式原则实现订阅发布模式,这种设计的优点是想订阅数据的类不需要继承订阅者类的抽象类,减少了一层类的继承;当然,具体情况需要可根据需求…

【Hadoop】- MapReduce YARN的部署[8]

目录 一、部署说明 二、集群规划 三、MapReduce配置文件 四、YARN配置文件 五、分发配置文件 六、集群启动命令 七、查看YARN的WEB UI 页面 一、部署说明 Hadoop HDFS分布式文件系统,我们会启动: NameNode进程作为管理节点DataNode进程作为工作节…

分类神经网络3:DenseNet模型复现

目录 DenseNet网络架构 DenseNet部分实现代码 DenseNet网络架构 论文原址:https://arxiv.org/pdf/1608.06993.pdf 稠密连接神经网络(DenseNet)实质上是ResNet的进阶模型(了解ResNet模型请点击),二者均是…

Hive基础5

一、窗口函数 聚合,取值函数 排序函数 over(partition by 分组字段 order by 字段 row between 起始行 and 结束行) /*创建部门表*/ CREATE TABLE dept (deptno INT PRIMARY KEY,dname VARCHAR(50) comment 部门名称,loc VARCHAR(50) comment 工作地点 ); ​ /*…

【数据结构】顺序表:与时俱进的结构解析与创新应用

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 数据结构与算法 先赞后看,已成习惯 创作不易,多多支持! 目录 一、数据结构的概念 二、顺序表(Sequence List) 2.1 线性表的概念以及结构 2.2 顺序表分类 …

【OpenHarmony-NDK技术】简单将cJson移植到OpenHarmony中,并在c层修改参数值再返回json

1、cJson的简单介绍 cJson - github网址 概述 一般使用cJson是,需要将json文本转化为json对象–编码,将json对象转化为json文本–解析。 git clone https://github.com/DaveGamble/cJSON.git 后留意cJSON.h和cJSON.h两个文件。 1、cJson的介绍 cJso…

【Node.js】02 —— Path模块全解析

🌟Node.js之Path模块探索🌈 📚引言 在Node.js的世界中,path模块就像一把万能钥匙🔑,它帮助我们理解和操作文件与目录的路径。无论你是初入Node.js殿堂的新手,还是久经沙场的老兵,理…

Python exe 文件反编译为 Python 脚本

文章目录 前言版本反编译Python 可执行文件(.exe)反编译打包一个简单的 .exe 可执行文件提取 pyc 文件使用脚本提取使用工具提取 将 .pyc 文件转换为 Python 脚本入口运行类非入口运行类转换补全后的 pyc 文件uncompyle6 反编译在线工具 可能遇到的问题P…

Meta通过开源Llama 3 LLM提高了标准

Meta 推出了 Llama 3,这是其最先进的开源大型语言模型(LLM)的下一代产品。这家科技巨头声称,Llama 3 在现实场景中建立了新的性能基准,超越了之前行业领先的模型,如 GPT-3.5。 Meta 在一篇博文中宣布了这一发布,并表示:"通过 Llama 3,我们致力于打造与当今最好的专有模型…

【Entity Framework】聊一聊EF如何使用数据库函数

【Entity Framework】聊一聊EF如何使用数据库函数 文章目录 【Entity Framework】聊一聊EF如何使用数据库函数一、数据库函数的类型二、内置函数与用户定义的函数四、聚合函数、标量函数和表值函数五、Niladic函数六、EF Core 中的数据库函数映射6.1 内置函数映射6.2 EF.Functi…