matplotlib从起点出发(15)_Tutorial_15_blitting

news2025/4/9 19:01:12

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 np

x = 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 : FigureCanvasAgg
            The canvas to work with, this only works for subclasses of the Agg
            canvas which have the `~FigureCanvasAgg.copy_from_bbox` and
            `~FigureCanvasAgg.restore_region` methods.

        animated_artists : Iterable[Artist]
            List of the artists to manage
        """
        self.canvas = canvas
        self._bg = None
        self._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.canvas
        if event is not None:
            if event.canvas != cv:
                raise RuntimeError
        self._bg = cv.copy_from_bbox(cv.figure.bbox)
        self._draw_animated()

    def add_artist(self, art):
        """
        Add an artist to be managed.

        Parameters
        ----------
        art : Artist

            The artist to be added.  Will be set to 'animated' (just
            to be safe).  *art* must be in the figure associated with
            the canvas this class is managing.

        """
        if art.figure != self.canvas.figure:
            raise RuntimeError
        art.set_animated(True)
        self._artists.append(art)

    def _draw_animated(self):
        """Draw all of the animated artists."""
        fig = self.canvas.figure
        for a in self._artists:
            fig.draw_artist(a)

    def update(self):
        """Update the screen with animated artists."""
        cv = self.canvas
        fig = cv.figure
        # 如果错过了绘制事件,则什么也不画
        if self._bg is None:
            self.on_draw(None)
        else:
            # 还原背景
            cv.restore_region(self._bg)
            # 绘制所有的动画artists
            self._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):
    #更新artists
    ln.set_ydata(np.sin(x + (j / 100) * np.pi))
    fr_number.set_text(f"frame: {j}")
    # 告诉位图传输管理器来更新
    bm.update()

在这里插入图片描述

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

在这里插入图片描述

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

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

相关文章

Element-plus DatePicker 日期选择器【正则校验时间范围】

效果图&#xff1a; 利用element-plus中的form表单验证完成效果。 <el-form-item label"检查计划截止日期&#xff1a;" prop"deadline"><el-date-pickerv-model"form.deadline"value-format"YYYY-MM-DD"style"width: …

计算机网络基础认识

本篇文章是我在B站上看到关于计算机网络的介绍视频收到的启发。本篇文章的内容来自【网络】半小时看懂<计算机网络>_哔哩哔哩_bilibili 一、物理层 从常理来说&#xff0c;进行连个设备之间的通讯&#xff0c;首先最容易想到的就是使用一根线连接两个设备进行通讯。但是…

基于单片机的空气质量检测系统设计

摘要:随着社会经济的不断发展,人们的生活水平日益提高,健康与养生成为了全民关注的热点话题,空气质量地不断下降也引起了社会的广泛关注,如何了解家居内空气质量的情况也成了亟需解决的问题。在此背景下,本文针对室内空气的质量问题设计了基于单片机的空气质量检测系统,…

js基础知识(2)

一、事件的含义 JavaScript事件是指在文档或者浏览器中发生的一些特定交互瞬间&#xff0c;比如打开某一个网页&#xff0c;浏览器加载完成后会触发load事件&#xff0c;当鼠标悬浮于某一个元素上时会触发hover事件&#xff0c;当鼠标点击某一个元素时会触发click事件等等。 三…

Excel 公式的定义、语法和应用(LOOKUP 函数、HLOOKUP 函数、VLOOKUP 函数;MODE.MULT 函数; ROUND 函数)

一、公式的定义和语法 二、公式的应用 附录 查找Excel公式使用方法的官方工具【强烈推荐&#xff01;&#xff01;&#xff01;】&#xff1a;Excel 函数&#xff08;按字母顺序&#xff09;【微软官网】 excel 函数说明语法LOOKUP 函数在向量或数组中查找值LOOKUP(lookup_va…

【AI相关】《这就是ChatGPT》读书笔记

《这就是ChatGPT》 斯蒂芬沃尔弗拉姆 这本书用了两天就一口气读完了&#xff0c;通篇读完后&#xff0c;这本书主要是介绍了ChatGPT怎么能做到生成内容的一些背后的原理逻辑&#xff0c;总结一下这本书是ChatGPT通过大量的数据&#xff08;这些数据来自网络、书籍等等类似于数据…

09.JAVAEE之网络初识

1.网络 单机时代 >局域网时代 >广域网时代 >移动互联网时代 1.1 局域网LAN 局域网&#xff0c;即 Local Area Network&#xff0c;简称LAN。 Local 即标识了局域网是本地&#xff0c;局部组建的一种私有网络。 局域网内的主机之间能方便的进行网络通信&#xff0…

Activiti——将绘制的流程图存入act数据库并进行流程推进与状态流转

文章目录 前言流程图入库操作 RepositoryService项目结构数据库连接配置文件入库Java测试代码zip 方式进行流程的批量部署 流程启动 RuntimeService待处理任务查看 TaskService流程状态的扭转查询流程定义信息 RepositoryService查询正在执行的流程实例 RuntimeService已部署流…

git简介及安装

Git | Git简介与安装 文章目录 Git | Git简介与安装一、Git简介二、Git安装Linux-centosLinux-ubuntu 一、Git简介 存在需求&#xff1a;对于一个文档&#xff0c;由于编写思路或者当前文档丢失&#xff0c;可能存在想要历史版本的需求&#xff0c;并且需要知道每个版本都修改了…

MySQL主从的应用

说明&#xff1a;本文介绍MySQL主从在实际中的应用。主从搭建和问题参考下面两篇文章&#xff1a; MySQL主从结构搭建 搭建MySQL主从结构时的问题 数据迁移 当我们搭建完MySQL主从&#xff0c;第一步当然是把历史数据导入到主从结构中。有以下两种方式&#xff1a; 开启主从…

Mysql个人总结

前言 又来水字数啦&#xff0c;这次主要讲一下MySQL的常用概念&#xff0c;难点的就必须上项目讲解了&#xff0c;而且比较基础面试基本都会问一些&#xff0c;用的话&#xff0c;不少优化都从这里入手 操作数据库 1、创建数据库 CREATE DATABASE [IF NOT EXISTS] 数据库名;…

如何设置微信自动回复?教你快速上手!

自动回复对于需要在微信上洽谈业务的人来说&#xff0c;无疑是非常实用的一个功能。 下面就一起来看看微信管理系统的机器人自动回复都有哪些设置吧&#xff01; 1、自动通过好友 只要有新的好友请求发送到你的微信账号&#xff0c;系统会自动通过该请求&#xff0c;无需手动…

rust 卸载重新安装 安装

原因&#xff1a;接触区块链时报错 linking with x86_64-w64-mingw32-gcc failed: exit code: 1 Rust编译需要C环境&#xff0c;如果你没有&#xff0c;Rust也能安装成功&#xff0c;只是无法编译代码 C的编译工具有两个&#xff0c;一个是msvc&#xff0c;也就是visual studi…

5个方便好用的Python自动化脚本

相比大家都听过自动化生产线、自动化办公等词汇&#xff0c;在没有人工干预的情况下&#xff0c;机器可以自己完成各项任务&#xff0c;这大大提升了工作效率。 编程世界里有各种各样的自动化脚本&#xff0c;来完成不同的任务。 尤其Python非常适合编写自动化脚本&#xff0…

DFS与回溯专题:全排列

DFS与回溯专题&#xff1a;全排列 题目链接: 46.全排列 题目描述 代码思路 回溯问题中的全排列&#xff0c;相对比组合、子集等问题&#xff0c;其元素可以颠倒顺序&#xff0c;所以在for循环中每层都是从头开始&#xff0c;无需标记更新起始位置 代码纯享版 class Soluti…

应用层协议 -- HTTPS 协议

目录 一、了解 HTTPS 协议 1、升级版的 HTTP 协议 2、理解“加密” 二、对称加密 1、理解对称加密 2、对称加密存在的问题 三、非对称加密 1、理解非对称加密 2、中间人攻击 3、CA 证书和数字签名 四、总结 一、了解 HTTPS 协议 1、升级版的 HTTP 协议 HTTPS 也是…

蜂窝物联:智慧水产养殖系统绘制“水世界”画卷

智慧水产养殖系统&#xff0c;融合了智能传感、无线传感网、通信、智能处理与智能控制等物联网技术的精髓&#xff0c;为养殖者绘制了一幅细致入微的“水世界”画卷。通过在线监测平台与各类智能传感器的协同作战&#xff0c;养殖者能够实时掌握养殖水质环境信息&#xff0c;仿…

AOC vs. DAC:哪个更适合您的网络需求?

在现代网络通信中&#xff0c;选择合适的连接线缆对于数据传输的稳定性和速度至关重要。两种常见的线缆类型是 AOC&#xff08;Active Optical Cable&#xff09; 和 DAC&#xff08;Direct Attach Cable&#xff09;。本文将详细介绍这两种线缆的特点、优势和适用场景&#xf…

ubuntu安装Qv2ray2.7.0及配置

需要下载两个文件&#xff0c;一个是zip文件&#xff0c;一个是AppImage执行程序。 执行AppImage需要先下在fuse sudo apt install libfuse2然后为AppImage赋予执行权限 sudo chmod x ./Qv2ray-v2.7.0-linux-x64.AppImage执行,执行前可以解压zip文件 ./Qv2ray-refs.tags.v1…

vue3环境搭建

环境准备&#xff1a; node环境(node.js官网)npm环境 上述两个环境存在版本要求所以安装最新的靠谱&#xff08;旧的环境存在不支持现象&#xff09; windows电脑 安装完node.js会带有npm mac电脑本身自带node和npm&#xff0c;但是需要升级 进入到你想创建前端项目的文件夹:…