Python绘图系统19:添加时间轴以实现动态绘图
文章目录
- 时间轴
- 单帧跳转
- 源代码
Python绘图系统:
- 📈从0开始的3D绘图系统📉一套3D坐标,多个函数📊散点图、极坐标和子图
- 自定义控件:绘图风格📉风格控件📊定制绘图风格
- 坐标设置进阶:动态更新组件📌导入外部文件📌导入txt
时间轴
三维并不是人类理解的极限,毕竟我们生活在思维时空中。所以接下来要做的,就是四维图形——加一个时间轴。
实际上,这个项目创建之初就已经考虑到动图绘制的问题,毕竟默认的绘图坐标是txyz。但是,如果想实现动图绘制,就必须要先设置一个额外的线程,用于动态更新图像,否则绘图循环压迫主进程,会导致界面变得奇卡无比。
接下来,就开始实现绘制动图的需求,第一步,绘制UI。先在setFrmCtrl中添加
# 动画控制
frm = ttk.Frame(frmCtrl, width=320)
frm.pack(side=tk.TOP, fill=tk.X)
self.setAnimateFrame(frm)
然后实现具体的self.setAnimateFrame
def setAnimateFrame(self, frm):pDct = dict(side=tk.LEFT, fill=tk.X, padx=2)self.aniDelay = tk.StringVar()self.aniDelay.set(100)ttk.Label(frm, text="延时/毫秒").pack(**pDct)ttk.Entry(frm, width=5, textvariable=self.aniDelay).pack(**pDct)self.aniFrameNum = tk.StringVar()self.aniFrameNum.set(100)ttk.Label(frm, text="帧数").pack(**pDct)ttk.Entry(frm, width=5, textvariable=self.aniFrameNum).pack(**pDct)self.tIndex = 0 # 当前帧数ttk.Button(frm, width=3, text= "⇦", command=self.btnPreFrame).pack(**pDct)ttk.Button(frm, width=3, text="▶", command=self.btnAniStart).pack(**pDct)ttk.Button(frm, width=3, text="⇨", command=self.btnNextFrame).pack(**pDct)def btnAniStart(self): passdef btnPreFrame(self): passdef btnNextFrame(self): pass

延时表示当自动绘制动图时,两帧间隔时间;帧数表示总共绘制的时间个数。三个按钮,分别用于向前一帧、向后一帧以及动态播放。
单帧跳转
坐标t的工作原理和xyz并不相同,毕竟每次调用时间参数的时候,都只需要调用某一点的时间。所以,现有的设置坐标数据的方法就不适用了,需要更改readDatas函数
# 读取坐标轴al的数据
def readDatas(self, al):dct = {}data = {}for flag in self.drawTypeDim.getDim():data[flag] = al.setData(flag, **dct)if flag=='t': dct['t'] = data['t'][self.tIndex]else:dct[flag] = data[flag]return data
然后再更新一下绘图函数:其实只是取消t作为绘图坐标轴的地位
def btnDrawImg(self):self.fig.clf()self.axDct = {}for al in self.als:ax = self.setDrawAxis(al)data = self.readDatas(al)draw = self.drawDct[al.getDrawType()]style = al.getStyle()keys = al.getDrawDim().replace('t',"")draw(ax, data, keys, style)self.fig.subplots_adjust(left=0.1, right=0.95, top=0.95, bottom=0.08)self.canvas.draw()
最后,实现一下btnNextFrame
def btnNextFrame(self): num = int(self.aniFrameNum.get())self.tIndex = (self.tIndex + 1) % numself.btnDrawImg()
效果如下,至此,我们离自动化动态绘图,只剩下一个多线程了。

源代码
本文只更改了ds.py中的源代码,其他代码可查看这篇博客:定制风格的绘图系统
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.filedialog import askopenfilenameimport matplotlib
import matplotlib as mpl
mpl.use('TkAgg')
import matplotlib.backends.backend_tkagg as mbb
from matplotlib.figure import Figureimport numpy as npfrom alist import AxisList
from base import DrawTypeclass DarwSystem():def __init__(self):self.root = tk.Tk()self.root.title("数据展示工具")self.data = {}self.als = []self.initConst()self.setFrmCtrl()frmFig = ttk.Frame(self.root)frmFig.pack(side=tk.LEFT,fill=tk.BOTH,expand=tk.YES)self.setFrmFig(frmFig)self.root.mainloop()def initConst(self):self.TYPES = ("点线图", "散点图", "条形图")self.drawDct = {"点线图" : self.drawPlot,"散点图" : self.drawScatter,"条形图" : self.drawBar}# ! 设置def setFrmCtrl(self):frmCtrl = ttk.Frame(self.root,width=320)frmCtrl.pack(side=tk.RIGHT, fill=tk.Y)# 主控Framefrm = ttk.Frame(frmCtrl, width=320)frm.pack(side=tk.TOP, fill=tk.X)self.setCtrlButtons(frm)# 动画控制frm = ttk.Frame(frmCtrl, width=320)frm.pack(side=tk.TOP, fill=tk.X)self.setAnimateFrame(frm)self.frmAxis = ttk.Frame(frmCtrl)self.frmAxis.pack(side=tk.TOP, fill=tk.X)self.addLast(None)# ! 工具栏def setCtrlButtons(self, frm):self.drawTypeDim = DrawType(frm)self.drawTypeDim.pack(side=tk.LEFT)ttk.Button(frm, text="📈",width=3,command=self.btnDrawImg).pack(side=tk.LEFT)ttk.Button(frm, text="📂",width=3,command=self.btnLoadData).pack(side=tk.LEFT)btn = ttk.Button(frm, text="+", width=3)btn.pack(side=tk.LEFT)btn.bind("<Button-1>", self.addLast)btn = ttk.Button(frm, text="-", width=3)btn.pack(side=tk.LEFT)btn.bind("<Button-1>", self.deleteLast)# ! 动画控制def setAnimateFrame(self, frm):pDct = dict(side=tk.LEFT, fill=tk.X, padx=2)self.aniDelay = tk.IntVar()self.aniDelay.set(100)ttk.Label(frm, text="延时/毫秒").pack(**pDct)ttk.Entry(frm, width=5, textvariable=self.aniDelay).pack(**pDct)self.aniFrameNum = tk.IntVar()self.aniFrameNum.set(100)ttk.Label(frm, text="帧数").pack(**pDct)ttk.Entry(frm, width=5, textvariable=self.aniFrameNum).pack(**pDct)self.tIndex = 0 # 当前帧数ttk.Button(frm, width=3, text= "⇦", command=self.btnPreFrame).pack(**pDct)ttk.Button(frm, width=3, text="▶", command=self.btnAniStart).pack(**pDct)ttk.Button(frm, width=3, text="⇨", command=self.btnNextFrame).pack(**pDct)def btnAniStart(self): passdef btnPreFrame(self): passdef btnNextFrame(self): num = self.aniFrameNum.get()self.tIndex = (self.tIndex + 1) % numself.btnDrawImg()# 添加一组坐标系def addLast(self, evt):title = f"坐标{len(self.als)}"al = AxisList(self.frmAxis, title, 1, [5,10,30], self.TYPES, self.drawTypeDim.getDct())al.pack(side=tk.TOP, fill=tk.X)self.als.append(al)# 删除一组坐标系def deleteLast(self, evt):self.als[-1].pack_forget()del self.als[-1]# 加载数据 // 暂时处于弃用状态def btnLoadData(self):name = askopenfilename()data = np.genfromtxt(name)for i, flag in enumerate('xyz'):if i >= data.shape[1]:returnself.AL.setOneMode(flag, "外部导入")self.data[flag] = self.AL.setData(flag, data = data[:,i])# 读取坐标轴al的数据def readDatas(self, al):dct = {}data = {}for flag in al.getDrawDim():data[flag] = al.setData(flag, **dct)if flag=='t': dct['t'] = data['t'][self.tIndex]else:dct[flag] = data[flag]return data# 设置绘图坐标def setDrawAxis(self, al):sub = int(al.getSub())print(sub)if sub in self.axDct:return self.axDct[sub]p = al.getProj() if p == "None":self.axDct[sub] = self.fig.add_subplot(sub)else:self.axDct[sub] = self.fig.add_subplot(sub, projection=p)return self.axDct[sub]# 单帧绘图函数def btnDrawImg(self):self.fig.clf()self.axDct = {}for al in self.als:ax = self.setDrawAxis(al)data = self.readDatas(al)draw = self.drawDct[al.getDrawType()]style = al.getStyle()keys = al.getDrawDim().replace('t',"")draw(ax, data, keys, style)self.fig.subplots_adjust(left=0.1, right=0.95, top=0.95, bottom=0.08)self.canvas.draw()def drawBar(self, ax, data, keys, style):ax.bar(data['x'], data['y'])def drawPlot(self, ax, data, keys, style):ax.plot(*[data[key] for key in keys], **style)def drawScatter(self, ax, data, keys, style):ax.scatter(*[data[key] for key in keys])def setFrmFig(self, frmFig):self.fig = Figure()self.canvas = mbb.FigureCanvasTkAgg(self.fig,frmFig)self.canvas.get_tk_widget().pack(side=tk.TOP,fill=tk.BOTH,expand=tk.YES)self.toolbar = mbb.NavigationToolbar2Tk(self.canvas,frmFig,pack_toolbar=False)self.toolbar.update()self.toolbar.pack(side=tk.RIGHT)if __name__ == "__main__":test = DarwSystem()
相关文章:
Python绘图系统19:添加时间轴以实现动态绘图
文章目录 时间轴单帧跳转源代码 Python绘图系统: 📈从0开始的3D绘图系统📉一套3D坐标,多个函数📊散点图、极坐标和子图自定义控件:绘图风格📉风格控件📊定制绘图风格坐标设置进阶&a…...
深度解析shell脚本的命令的原理之rm
rm 是 Unix/Linux 系统中的一个基本命令,用于删除文件或目录。以下是对这个命令的深度分析: 基本操作:rm 命令删除一个或多个文件或目录。这是通过从文件系统中移除链接来完成的。在 Unix/Linux 中,文件是通过链接(可以…...
RPA机器人流程自动化专题培训大纲(供大家参考使用)
一、RPA机器人流程自动化概述 RPA的定义和发展历程RPA的应用场景和优势RPA与人工智能的关系 二、RPA机器人流程自动化基础知识 RPA的基本原理和技术架构RPA的常用技术和工具RPA的编程语言和开发环境 三、RPA机器人流程自动化实战应用 如何进行业务流程分析与优化如何利用R…...
Python用若干列的数据多条件筛选、去除Excel数据并批量绘制直方图
本文介绍基于Python,读取Excel数据,以一列数据的值为标准,对这一列数据处于指定范围的所有行,再用其他几列数据数值,加以筛选与剔除;同时,对筛选与剔除前、后的数据分别绘制若干直方图ÿ…...
驱动开发,IO多路复用实现过程,epoll方式
1.框架图 被称为当前时代最好用的io多路复用方式; 核心操作:一棵树(红黑树)、一张表(内核链表)以及三个接口; 思想:(fd代表文件描述符) epoll要把检测的事件…...
java在mysql中查询内容无法塞入实体类中,报错 all elements are null
目录 一、问题描述二、解决方案 一、问题描述 java项目中整体配置了mysql的驼峰式字段匹配规则。 mybatis.configuration.map-underscore-to-camel-casetrue由于项目需求,需要返回字段为file_id,file_url,并且放入实体类中,实体…...
Linux 挂载
挂载需要挂载源和挂载点 虚拟机本身就有的挂源 添加硬件 重启虚拟机 操作程序 sudo fdisk -l //以管理员权限查看电脑硬盘使用情况sudo mkfs.ext4 /dev/sdb //以管理员身份格式化硬盘sudo mkdir guazai //创建挂载文件夹 sudo mount /dev/sdb/guazai //将挂载源接上挂载点 s…...
[面试] 15道最典型的k8s面试题
文章目录 在 Kubernetes 中,有以下常见的资源对象:1.什么是 Kubernetes?它的主要特点是什么?2. Kubernetes 中的 Pod 是什么?它的作用是什么?3.Kubernetes 中的 Deployment 和 StatefulSet 有何区别&#x…...
lintcode 552 · 创建最大数 【算法 数组 贪心 hard】
题目 https://www.lintcode.com/problem/552/description 描述 给出两个长度分别是m和n的数组来表示两个大整数,数组的每个元素都是数字0-9。从这两个数组当中选出k个数字来创建一个最大数,其中k满足k < m n。选出来的数字在创建的最大数里面的位置…...
ModbusTCP服务端
1在Device下,添加设备net: 公交车。 2在net下添加 ModbusTCP...
Middleware ❀ Hadoop功能与使用详解(HDFS+YARN)
文章目录 1、服务概述1.1 HDFS1.1.1 架构解析1.1.1.1 Block 数据块1.1.1.2 NameNode 名称节点1.1.1.3 Secondary NameNode 第二名称节点1.1.1.4 DataNode 数据节点1.1.1.5 Block Caching 块缓存1.1.1.6 HDFS Federation 联邦1.1.1.7 Rack Awareness 机架感知 1.1.2 读写操作与可…...
Matlab图像处理-从RGB转换为HSV
从RGB转换为HSV HSV彩色系统基于圆柱坐标系。从RGB转换为HSV需要开发将(笛卡儿坐标系中的)RGB值映射到圆柱坐标系的公式。多数计算机图形学教材中已详细推导了这一公式,故此处从略。 从RGB转换为HSV的MATLAB函数是rgb2hsv,其语法为: hsv_imag…...
iOS Error Domain=PHPhotosErrorDomain Code=3300
AVCapturePhoto的数据保存到 PHPhotoLibrary的时候报错Error DomainPHPhotosErrorDomain Code3300解决代码(也可以使用addResourceWithType:data:options:来添加数据到request,JEPG的实测可以,raw的不确定): [PHPhoto…...
LeetCode(力扣)435. 无重叠区间Python
LeetCode435. 无重叠区间 题目链接代码 题目链接 https://leetcode.cn/problems/non-overlapping-intervals/ 代码 class Solution:def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:if not intervals:return 0intervals.sort(keylambda x: x[0])co…...
opencv c++实现鼠标框选区域并显示选择的图片区域
OpenCV可以使用setMouseCallback设置鼠标事件的回调函数,从而然后根据需要进行处理。 setMouseCallback原型为: void cv::setMouseCallback(const cv::String& windowName, MouseCallback onMouse, void* userData = 0); 其中,参数说明如下:windowName:窗口名称 onMo…...
Python实现自主售卖机
1 问题 在python中我们常常使用到条件判断,if语句时常见的条件判断语句之一。那么如何使用if语句实现根据情况自动选择商品进行售卖呢? 2 方法 根据if语句执行时从上往下执行的特点,使用if语句、dict和list来实现整个流程。 代码清单 1 drink…...
任务复杂度与人机
任务复杂度计算是指根据任务的难易程度和需要的资源投入来评估任务的复杂程度。一般来说,任务复杂度计算会考虑以下几个因素: 难度程度:任务的难度程度是指完成任务所需要的知识、技能和经验等的要求。较高的难度程度会增加任务的复杂度。任务…...
Windows关闭zookeeper、rocketmq日志输出以及修改rocketmq的JVM内存占用大小
JDK-1.8zookeeper-3.4.14rocketmq-3.2.6 zookeeper 进入到zookeeper的conf目录 清空配置文件,只保留下面这一行。zookeeper关闭日志输出相对简单。 log4j.rootLoggerOFFrocketmq 进入到rocketmq的conf目录 logback_broker.xml <?xml version"1.0&q…...
Convai:让虚拟游戏角色更智能的对话AI人工智能平台
【产品介绍】 名称 Convai 具体描述 Convai是一款专为虚拟世界而设计的对话人工智能平台,它可以让你为你的游戏或应用中的角色 赋予人类般的对话能力。Convai利用了最先进的生成式对话人工智能技术,让你的角色可以…...
【送书活动】大模型赛道如何实现华丽的弯道超车
文章目录 导读前言AI/ML 模型训练任务对数据平台的需求01 具备对海量小文件的频繁数据访问的 I/O 效率02 提高 GPU 利用率,降低成本并提高投资回报率03 支持各种存储系统的原生接口04 支持单云、混合云和多云部署 核心密码01 通过数据抽象化统一数据孤岛02 通过分布…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
