tkinter打造三维绘图系统,附源代码

news2024/11/24 22:39:28

文章目录

    • 输入数据
    • 加载数据
    • 绘图函数
    • 源代码

Python绘图系统系列:将matplotlib嵌入到tkinter 简单的绘图系统 数据导入

输入数据

三维绘图需要一个新的坐标变量,设置为z,这个改改UI就可以办到,并不困难。但是,此前用于设置x和y数据的函数实在是过于雷同,如果再写一个设置z轴的,那么这个绘图系统里就相当于是有了3个一毛一样的函数,十分离谱,所以为了简化代码,可以将所有的数据输入框设为一个字典,然后挨个生成xyz的输入框,其中setFrmCtrl函数如下

def setFrmCtrl(self, frmCtrl):
    frm = ttk.Frame(frmCtrl, width=320)
    frm.pack(side=tk.TOP, fill=tk.X)
    self.setCtrlButtons(frm)

    self.entrys = {}
    for flag in 'xyz':
        frm = ttk.Frame(frmCtrl)
        frm.pack(side=tk.TOP, fill=tk.X)
        self.setFrmAxis(frm, flag)

setFrmAxis则没什么好说的,只是新增了一个参数而已。

def setFrmAxis(self, frm, flag):
    tk.Label(frm, text=flag).pack(side=tk.LEFT)
    self.entrys[flag] = tk.Entry(frm)
    self.entrys[flag].pack(side=tk.LEFT, fill=tk.X)    

加载数据

此前,分别用self.xsself.ys来表示x和y轴数据,这又是一个雷同。为了简化代码,将变量也设做字典,在初始化的init函数中添加

self.data = {}

然后将加载数据的函数改写为

def btnLoadData(self):
    name = askopenfilename()
    data = np.genfromtxt(name)
    for flag, i in enumerate()'xyz':
        if i >= data.shape[1]:
            return
        self.data[flag] = data[:,i]
        setEntry(self.entrys[flag], 'data')

然后新建一个用来读取Entry的函数,考虑到x和y都有可能用类似1,1,5的形式生成,所以先做一个检测数组的全局函数

def detectArray(s):
    return s.rstrip('0123456789:, ')==''

然后是readEntrys函数,考虑到在函数表达式中,用x和y指代self.data[‘x’]和selfdata[‘y’],所以需要新建局部变量x和y,以确保eval函数的正常使用。

def readEntrys(self):
    for flag in 'xyz':
        label = self.entrys[flag].get()
        if label != 'data':
            if detectArray(label):
                label = f"np.linspace({label})"
            self.data[flag] = eval(self.entrys[flag].get())
        if flag =='x' : x = self.data['x']
        elif flag =='y' : y = self.data['y']        
    
    if self.entrys['z'].get()=="":
        del self.data['z']

绘图函数

最后,就是绘图功能的实现,由于有了readEntrys函数,从而btnDrawImg函数变得更加专注,只需复制调用专门的绘图函数就可以了。三维绘图函数和二维绘图函数其实没什么区别,只要绘制的还是plot图,区别只是多加了一个z轴坐标而已。

def btnDrawImg(self):
    self.readEntrys()
    self.fig.clf()
    if 'z' in self.data: 
        self.drawPlot3D()
    else:
        self.drawPlot()
    self.fig.subplots_adjust(left=0.1, right=0.95, top=0.95, bottom=0.08)
    self.canvas.draw()

由于把用于设置边框宽度的subplots_adjust以及canvas.draw放在了btnDrawImg这个函数中,所以drawPlot函数也需要做适当的精简。而drawPlot3D只是将projection设为‘3d’,同时添加一组z坐标而已。

def drawPlot(self):
        ax = self.fig.add_subplot()
        ax.plot(self.data['x'], self.data['y'])

def drawPlot3D(self):
    ax = self.fig.add_subplot(projection='3d')
    ax.plot(self.data['x'], self.data['y'], self.data['z'])

至此,就可以看一下效果了

在这里插入图片描述

源代码

最后,附上源代码

import tkinter as tk
import tkinter.ttk as ttk
from tkinter.filedialog import askopenfilename

import matplotlib as mpl
mpl.use('TkAgg')
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import (
    FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure

import numpy as np

def setEntry(e, text):
    e.delete(0, "end")
    e.insert(0, text)

def detectArray(s):
    return s.rstrip('0123456789:, ')==''

class DarwSystem():
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("数据展示工具")

        self.data = {}

        frmCtrl = ttk.Frame(self.root,width=320)
        frmCtrl.pack(side=tk.RIGHT, fill=tk.Y)
        self.setFrmCtrl(frmCtrl)

        frmFig = ttk.Frame(self.root)
        frmFig.pack(side=tk.LEFT,fill=tk.BOTH,expand=tk.YES)
        self.setFrmFig(frmFig)
        
        self.root.mainloop()
    
    def setFrmCtrl(self, frmCtrl):
        frm = ttk.Frame(frmCtrl, width=320)
        frm.pack(side=tk.TOP, fill=tk.X)
        self.setCtrlButtons(frm)

        self.entrys = {}
        for flag in 'xyz':
            frm = ttk.Frame(frmCtrl)
            frm.pack(side=tk.TOP, fill=tk.X)
            self.setFrmAxis(frm, flag)

    def setFrmAxis(self, frm, flag):
        tk.Label(frm, text=flag).pack(side=tk.LEFT)
        self.entrys[flag] = tk.Entry(frm)
        self.entrys[flag].pack(side=tk.LEFT, fill=tk.X)    

    def setCtrlButtons(self, frm):
        ttk.Button(frm, text="绘图",width=5,
            command=self.btnDrawImg).pack(side=tk.LEFT)
        ttk.Button(frm, text="加载",width=5,
            command=self.btnLoadData).pack(side=tk.LEFT)

    def btnLoadData(self):
        name = askopenfilename()
        data = np.genfromtxt(name)
        for i, flag in enumerate('xyz'):
            if i >= data.shape[1]:
                return
            self.data[flag] = data[:,i]
            setEntry(self.entrys[flag], 'data')
    
    def readEntrys(self):
        for flag in 'xyz':
            label = self.entrys[flag].get()
            if label=="":
                continue
            if label != 'data':
                if detectArray(label):
                    label = f"np.linspace({label})"
                self.data[flag] = eval(self.entrys[flag].get())
            if flag =='x' : x = self.data['x']
            elif flag =='y' : y = self.data['y']        
        
        if self.entrys['z'].get()=="":
            del self.data['z']

    def btnDrawImg(self):
        self.readEntrys()
        self.fig.clf()
        if 'z' in self.data:
            self.drawPlot3D()
        else:
            self.drawPlot()
        self.fig.subplots_adjust(left=0.1, right=0.95, top=0.95, bottom=0.08)
        self.canvas.draw()
        
    def drawPlot3D(self):
        ax = self.fig.add_subplot(projection='3d')
        ax.plot(self.data['x'], self.data['y'], self.data['z'])

    def drawPlot(self):
        ax = self.fig.add_subplot()
        ax.plot(self.data['x'], self.data['y'])

    def setFrmFig(self, frmFig):
        self.fig = Figure()
        self.canvas = FigureCanvasTkAgg(self.fig,frmFig)
        self.canvas.get_tk_widget().pack(
            side=tk.TOP,fill=tk.BOTH,expand=tk.YES)
        self.toolbar = NavigationToolbar2Tk(self.canvas,frmFig,
            pack_toolbar=False)
        self.toolbar.update()
        self.toolbar.pack(side=tk.RIGHT)

if __name__ == "__main__":
    test = DarwSystem()

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

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

相关文章

git安装介绍

一、分布式版本控制系统Git概述 1.1 分布式版本控制系统Git介绍 版本控制定义 记录和跟踪项目中各文件内容的改动变化 保存项目的版本历史,以及改动原因,从而让用户能够查看各个历史版本 版本控制系统也是帮助人员进行协作开发的利器 为什么需要版本…

WebRTC音视频通话-WebRTC本地视频通话使用ossrs服务搭建

iOS开发-ossrs服务WebRTC本地视频通话服务搭建 之前开发中使用到了ossrs,这里记录一下ossrs支持的WebRTC本地服务搭建。 一、ossrs是什么? ossrs是什么呢? SRS(Simple Realtime Server)是一个简单高效的实时视频服务器,支持RTM…

福康源:用孝道温暖每一个心灵,共筑幸福健康新人生!

福康源:用孝道温暖每一个心灵,共筑幸福健康新人生 孝道的光芒:福康源的初心 在浮躁的现代社会,孝道的力量正被越来越多的人忽略。然而,福康源的初心却始终坚守孝顺的真谛。孝道不仅是对父母的敬爱,更是一种…

【解析postman工具的使用---基础篇】

postman前端请求详解 主界面1.常见类型的接口请求1.1 查询参数的接口请求1.1.1 什么是查询参数?1.1.2 postman如何请求 1.2 ❤表单类型的接口请求1.2.1 复习下http请求1.2.2❤ 什么是表单 1.3 上传文件的表单请求1.4❤ json类型的接口请求 2. 响应接口数据分析2.1 postman的响…

程序设计 树基础

✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。 🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心&…

Lorilla LLM - 面向API调用生成的专用AI大模型

Gorilla 是一种先进的大型语言模型 (LLM),旨在与各种 API 有效交互,从而增强 LLM 在实际应用中的功能。 Gorilla LLM的相关链接:官网 | github | 论文。 推荐:用 NSDT编辑器 快速搭建可编程3D场景 1、Gorilla LLM简介 通过使用自…

CentOS 项目作出声明,宣称自家 Linux 社区 “始终向所有人开放”

导读在红帽 RHEL 开源事件后,许多兼容 RHEL 的发行版最近都进行了表态,CentOS 项目也在日前作出了声明,宣称自家社区 “始终向所有人开放”。 据悉,CentOS 项目董事会日前在官方博客发布了一则公告,内容主要涉及“ Ce…

拒绝摆烂!C语言练习打卡第一天

🔥博客主页:小王又困了 📚系列专栏:每日一练 🌟人之为学,不日近则日退 ❤️感谢大家点赞👍收藏⭐评论✍️ 🗒️前言: 在前面我们学习完C语言的所以知识,当…

LangChain手记 Models,Prompts and Parsers

整理并翻译自DeepLearning.AILangChain的官方课程:Models,Prompts and Parsers 模型,提示词和解析器(Models, Prompts and Parsers) 模型:大语言模型提示词:构建传递给模型的输入的方式解析器:…

NAS搭建指南二——影视资源中心

1. 刮削 这一部分是利用 tinyMediaManager 进行影视资源的评分、简介以及图片的搜集工作tinyMediaManager 官方网站地址下载及安装过程:略我的主要修改的设置项如下所示: 使用方法: a. 点击更新媒体库 b. 选择影片–>右键单击–>…

Ubuntu 20.04(服务器版)安装 Anaconda

0、Anaconda介绍 Anaconda是一个开源的Python发行版本,包含了包括Python、Conda、科学计算库等180多个科学包及其依赖项。因此,安装了Anaconda就不用再单独安装CUDA、Python等。 CUDA,在进行深度学习的时候,需要用到GPU&#xf…

生信分析pandas数据处理 Python简明教程 | 视频18

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在:https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

软件开发中常用数据结构介绍:C语言链表

工作之余来写写C语言相关知识,以免忘记。今天就来聊聊C语言链表,我是分享人M哥,目前从事车载控制器的软件开发及测试工作。 学习过程中如有任何疑问,可底下评论! 如果觉得文章内容在工作学习中有帮助到你,麻…

干不完根本干不完,我也不想加班,快来围观时间管理大师

时间不够用,怎么办? 成功不靠加班。生产队的驴都不加班,你加什么班?到点就下班,该玩玩,该学习认真学,累了就睡觉。 你可以做任何事,但不必做所有事。 时间管理,不是管…

(十七)大数据实战——Hive的hiveserver2服务安装部署

前言 HiveServer2 是 Apache Hive 的一个服务器端组件,用于支持客户端与 Hive 进行交互和执行查询。HiveServer2服务的作用是提供jdbc/odbc接口,为用户提供远程访问Hive数据的功能。HiveServer2 允许多个客户端同时连接并与 Hive 交互。这些客户端可以通…

HOT91-不同路径

leetcode原题链接:不同路径 题目描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )…

shell编程免交互

免交互 定义: 一键执行,无需人工干预,不需要人为控制,就可以完成的操作,继续自动化运维 免交互在linux中的运用: 对于Linux操作系统中,有许多操作都会触及到交互(根据系统的指示做…

OpenCV项目开发实战--相机校准—并附实例Python/C++代码实现

介绍 相机标定是计算机视觉中的一项基本任务在 3D 重建、对象跟踪、增强现实和图像分析等各种应用中至关重要。准确的校准通过校正失真和估计相机的内在和外在参数来确保精确的测量和可靠的分析。这本综合指南深入探讨了相机校准的原理、技术和算法。我们探索获取相机的内在和…

在 Linux 虚拟机上使用 Azure 自定义脚本扩展版本

参考 azure创建虚拟机,创建虚拟机注意入站端口规则开放80端口、 2.转到资源,点击扩展应用程序,创建存储账户,创建容器,上传文件,选择文件,会自动执行部署。 apt-get update -y && apt-get insta…

电信流失用户画像

三大运营商电信、联通、移动,都想扩大自己的客户群体。据研究,获取新客户所需的成本远高于保留现有客户的成本。因此为了满足在激烈竞争中的优势,提前预测出用户是否会流失,采取保留措施成为一大挑战。本文和你一起探索电信流失客…