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.mzph.cn/web/1512.shtml

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

相关文章

揭开ChatGPT面纱(3):使用OpenAI进行文本情感分析(embeddings接口)

文章目录 一、embeddings接口解析二、代码实现1.数据集dataset.csv2.代码3.运行结果 openai版本1.6.1 本系列博客源码仓库:gitlab,本博客对应文件夹03 在这一篇博客中我将使用OpenAI的embeddings接口判断21条服装评价是否是好评。 首先来看实现思路&am…

Llama3新一代 Llama模型

最近,Meta 发布了 Llama3 模型,从发布的数据来看,性能已经超越了 Gemini 1.5 和 Claud 3。 Llama 官网说,他们未来是要支持多语言和多模态的,希望那天赶紧到来。 未来 Llama3还将推出一个 400B大模型,目前…

计算机网络——数据链路层(介质访问控制)

计算机网络——数据链路层(介质访问控制) 介质访问控制静态划分信道动态划分信道ALOHA协议纯ALOHA(Pure ALOHA)原理特点 分槽ALOHA(Slotted ALOHA)原理特点 CSMA协议工作流程特点 CSMA-CD 协议工作原理主要…

JVM虚拟机(十二)ParallelGC、CMS、G1垃圾收集器的 GC 日志解析

目录 一、如何开启 GC 日志?二、GC 日志分析2.1 PSPO 日志分析2.2 ParNewCMS 日志分析2.3 G1 日志分析 三、GC 发生的原因3.1 Allocation Failure:新生代空间不足,触发 Minor GC3.2 Metadata GC Threshold:元数据(方法…

在React中的函数组件和类组件——附带示例的对比

在React中,创建组件有两种主要方式:函数组件和类组件。每种方式都有自己的语法和用例,尽管随着React Hooks的引入,它们之间的差距已经显著缩小。但选择适当的组件类型对于构建高效和可维护的React应用程序仍然非常关键。 在本文中…

3. 指标收口

在数据仓库建设中,“指标收口”指的是在数据仓库的指标体系设计和实施过程中,对指标进行统一管理和优化,以确保数据的一致性、准确性。 对“指标收口”的详细理解: 1、明确指标定义和计算方法:在数据仓库建设中&#…

【数据结构|C语言版】算法效率和复杂度分析

前言1. 算法效率2. 大O的渐进表示法3. 时间复杂度3.1 时间复杂度概念3.2 时间复杂度计算举例 4. 空间复杂度4.1 空间复杂度的概念4.2 空间复杂度计算举例 5. 常见复杂度对比结语 ↓ 个人主页:C_GUIQU 个人专栏:【数据结构(C语言版&#xff09…

Kafka源码分析(四) - Server端-请求处理框架

系列文章目录 Kafka源码分析-目录 一. 总体结构 先给一张概览图: 服务端请求处理过程涉及到两个模块:kafka.network和kafka.server。 1.1 kafka.network 该包是kafka底层模块,提供了服务端NIO通信能力基础。 有4个核心类:…

【Django】django.core.exceptions.AppRegistryNotReady: Apps aren‘t loaded yet.

其中django后台manage.py入口程序报错,检索很多问题解决方案,这里记录下个人问题原因 1.django启动异常问题详情 django.core.exceptions.AppRegistryNotReady: Apps aren’t loaded yet. 2.问题原因 Python第三方包安装版本不一致或缺少依赖包&…

Flink窗口机制

1.窗口的概念 时间是为窗口服务的。窗口是什么?为什么会有窗口呢? (1)Flink要处理的数据,一般是从Kafka过来的流式数据,如果只是单纯地统计流的数据量,是没办法统计的。 (2&#xff…

C语言程序设计:简易版的printf函数实现

简易版的printf函数实现 功能说明 (1)使用putchar函数、va可变参完成printf函数基本功能的实现; (2)函数说明: 实现对下列数据类型的输出,并返回成功输出打印的字符个数: 整数&…

在CSDN创作了6个月,我收获了什么?文末送书~

作者主页:阿玥的小东东主页! 正在学习:python和C/C 期待大家的关注哦 目录 一次很好的机会,让我开始了CSDN之旅 首先来看看我的几位领路人 创作动力 1W粉丝 在CSDN我收获了什么? 很高的展现量 认证创作者身份 社…

Java Web常见框架

1、Spring Framework Spring是一个非常强大的框架,用于构建企业级应用程序。它提供了全面的编程和配置模型。 2、Spring Boot 基于Spring,它简化了配置过程,使得启动和运行基于Spring的应用程序变得更快,更容易。 3、Hibernat…

【Linux】系统安全及应用

目录 一、账号安全基本措施 1.系统账号清理 2.密码安全控制 3.历史命令安全管理 4.限制su切换用户 1)将信任的用户加入到wheel组中 2)修改su的PAM认证配置文件 5.ssh远程登录输入三次密码错误则锁定用户 二、Linux中的PAM安全认证 1.su命令的…

Redis入门到通关之数据结构解析-动态字符串SDS

文章目录 Redis数据结构-动态字符串动态扩容举例二进制安全SDS优点与C语言中的字符串的区别 Redis数据结构-动态字符串 我们都知道 Redis 中保存的Key是字符串,value 往往是字符串或者字符串的集合。可见字符串是 Redis 中最常用的一种数据结构。 不过 Redis 没有…

Android Studio超级详细讲解下载、安装配置教程(建议收藏)

博主介绍:✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉着互联网精神开源贡献精神,答疑解惑、坚持优质作品共享。本人是掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战,深受全网粉丝喜爱与支持✌有…

ES是什么?ES的使用场景有哪些?分词器??

一、ES是什么??? 1、Elasticsearch 是一个基于 Apache Lucene 构建的开源分布式搜索引擎和分析引擎。同时还可以被视为一种特殊的数据库,具体而言,它是一种分布式、面向文档的NoSQL数据库,专为全文搜索和数…

贪吃蛇游戏实现(VS编译环境)

贪吃蛇游戏 🥕个人主页:开敲🍉 🔥所属专栏:C语言🍓 🌼文章目录🌼 0. 前言 1. 游戏背景 2. 实现后游戏画面展示 3. 技术要求 4. Win32 API介绍 4.1 Win32 API 4.2 控制台程序 4.…

Java之类和对象

一面向对象的初步认知 1.什么是面向对象 Java是一门纯面向对象的语言(Object Oriented Program,简称OOP),在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。用面向对象的思想…

嵌入式物联网实战开发笔记-乐鑫ESP32开发环境ESP-IDF搭建【doc.yotill.com】

乐鑫ESP32入门到精通项目开发参考百例下载: 链接:百度网盘 请输入提取码 提取码:4e33 3.1 ESP-IDF 简介 ESP-IDF(Espressif IoT Development Framework)是乐鑫(Espressif Systems)为 ESP 系列…