python使用tkinter打造三維繪圖系統(tǒng)的示例代碼
Python繪圖系統(tǒng)系列:python將matplotlib嵌入到tkinter中的步驟詳解_python_腳本之家 (jb51.net)
輸入數(shù)據(jù)
三維繪圖需要一個(gè)新的坐標(biāo)變量,設(shè)置為z,這個(gè)改改UI就可以辦到,并不困難。但是,此前用于設(shè)置x和y數(shù)據(jù)的函數(shù)實(shí)在是過(guò)于雷同,如果再寫(xiě)一個(gè)設(shè)置z軸的,那么這個(gè)繪圖系統(tǒng)里就相當(dāng)于是有了3個(gè)一毛一樣的函數(shù),十分離譜,所以為了簡(jiǎn)化代碼,可以將所有的數(shù)據(jù)輸入框設(shè)為一個(gè)字典,然后挨個(gè)生成xyz的輸入框,其中setFrmCtrl函數(shù)如下
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 則沒(méi)什么好說(shuō)的,只是新增了一個(gè)參數(shù)而已。
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) 加載數(shù)據(jù)
此前,分別用 self.xs 和 self.ys 來(lái)表示x和y軸數(shù)據(jù),這又是一個(gè)雷同。為了簡(jiǎn)化代碼,將變量也設(shè)做字典,在初始化的init函數(shù)中添加
self.data = {}然后將加載數(shù)據(jù)的函數(shù)改寫(xiě)為
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')然后新建一個(gè)用來(lái)讀取Entry的函數(shù),考慮到x和y都有可能用類(lèi)似 1,1,5 的形式生成,所以先做一個(gè)檢測(cè)數(shù)組的全局函數(shù)
def detectArray(s):
return s.rstrip('0123456789:, ')==''然后是readEntrys函數(shù),考慮到在函數(shù)表達(dá)式中,用x和y指代self.data[‘x’]和selfdata[‘y’],所以需要新建局部變量x和y,以確保eval函數(shù)的正常使用。
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']繪圖函數(shù)
最后,就是繪圖功能的實(shí)現(xiàn),由于有了readEntrys函數(shù),從而btnDrawImg函數(shù)變得更加專(zhuān)注,只需復(fù)制調(diào)用專(zhuān)門(mén)的繪圖函數(shù)就可以了。三維繪圖函數(shù)和二維繪圖函數(shù)其實(shí)沒(méi)什么區(qū)別,只要繪制的還是plot圖,區(qū)別只是多加了一個(gè)z軸坐標(biāo)而已。
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()由于把用于設(shè)置邊框?qū)挾鹊膕ubplots_adjust以及canvas.draw放在了btnDrawImg這個(gè)函數(shù)中,所以drawPlot函數(shù)也需要做適當(dāng)?shù)木?jiǎn)。而drawPlot3D只是將projection設(shè)為‘3d’,同時(shí)添加一組z坐標(biāo)而已。
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("數(shù)據(jù)展示工具")
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()以上就是python使用tkinter打造三維繪圖系統(tǒng)的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于python tkinter三維繪圖系統(tǒng)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python連接mysql數(shù)據(jù)庫(kù)并讀取數(shù)據(jù)的實(shí)現(xiàn)
這篇文章主要介紹了python連接mysql數(shù)據(jù)庫(kù)并讀取數(shù)據(jù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Python 中如何使用 virtualenv 管理虛擬環(huán)境
這篇文章主要介紹了Python 中使用 virtualenv 管理虛擬環(huán)境的方法,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2021-01-01
在python代碼中加入環(huán)境變量的語(yǔ)句操作
這篇文章主要介紹了在python代碼中加入環(huán)境變量的語(yǔ)句操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
python+OpenCV實(shí)現(xiàn)車(chē)牌號(hào)碼識(shí)別
這篇文章主要介紹了python+OpenCV實(shí)現(xiàn)車(chē)牌號(hào)碼識(shí)別,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
Python學(xué)習(xí)之線(xiàn)程池與GIL全局鎖詳解
本文我們將學(xué)習(xí)線(xiàn)程池的創(chuàng)建與全局鎖。線(xiàn)程池的創(chuàng)建于進(jìn)程池的原理是相同的;關(guān)于GIL全局鎖,暫時(shí)沒(méi)有代碼上的練習(xí),而是對(duì)其概念進(jìn)行一個(gè)簡(jiǎn)單的啟蒙,感興趣的可以了解一下2022-04-04
Python開(kāi)發(fā)虛擬環(huán)境使用virtualenvwrapper的搭建步驟教程圖解
virtualenvwrapper是用來(lái)管理virtualenv的擴(kuò)展包,用著很方便。這篇文章主要介紹了Python開(kāi)發(fā)虛擬環(huán)境使用virtualenvwrapper的搭建步驟 ,需要的朋友可以參考下2018-09-09
一文帶你了解Python中不同數(shù)據(jù)對(duì)象的空值校驗(yàn)方法
空值校驗(yàn)在數(shù)據(jù)處理和應(yīng)用程序開(kāi)發(fā)中是一個(gè)非常重要的任務(wù),Python提供了多種方式來(lái)檢查不同數(shù)據(jù)對(duì)象(如字符串、列表、字典、集合等)是否為空或包含空值,下面就跟隨小編一起來(lái)學(xué)習(xí)一下吧2024-01-01
python批量導(dǎo)入數(shù)據(jù)進(jìn)Elasticsearch的實(shí)例
今天小編就為大家分享一篇python批量導(dǎo)入數(shù)據(jù)進(jìn)Elasticsearch的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05

