Python数据分析工具 - 基于Tkinter和Matplotlib的图形化界面
Python数据分析工具 - 基于Tkinter和Matplotlib的图形化界面
这份代码实现了一个简单的数据分析工具界面,包含了数据导入、数据预处理、数据可视化、模型训练和预测等多个功能,可以方便地对数据进行分析和建模。
代码主要分为两个类:LoginWindow 和 Application。
1. 登陆界面 (LoginWindow)
登陆界面包含用户名和密码输入框以及登陆按钮,当用户输入正确的用户名和密码时,会跳转到 Application 界面。
2. 数据分析工具界面 (Application)
数据分析工具界面包含了导入数据、数据预处理、数据可视化、模型训练和预测等功能。具体实现如下:
(1) 导入数据 (load_data): 该函数会弹出文件选择对话框,获取要导入的数据集文件,并读取CSV文件并显示在文本框。
(2) 数据预处理 (preprocess_data): 该函数会进行数据预处理(标准化和PCA降维),并获取scaler 和 pca 对象。
(3) 绘制散点图 (plot_scatter): 该函数会绘制散点图,并在图形化界面中显示。
(4) 绘制折线图 (plot_line): 该函数会绘制折线图,并在图形化界面中显示。
(5) 模型训练 (train_model): 该函数会进行特征选择和模型训练(决策树),并获取clf、X_train、X_test、y_train 和 y_test 对象。
(6) 输出准确度 (output_accuracy): 该函数会输出模型在训练集和测试集上的准确度。
(7) 评估属性重要性 (evaluate_importance): 该函数会评估属性重要性,并在图形化界面中显示。
(8) 输出最优结果和参数 (output_best_result): 该函数会输出最优结果和参数,并在图形化界面中显示。
(9) 预测新数据 (predict_data): 该函数会预测新数据,并在图形化界面中显示预测结果。
3. 其他细节
为了美化界面,代码中使用了图片作为背景,并对按钮和文本框等控件进行了一些布局和颜色调整。同时,代码还使用了Tkinter的ttk.Button 代替 Button,以增加界面的美观性。
代码示例:
import tkinter as tk
from tkinter import messagebox, filedialog
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn import tree
import graphviz
from sklearn.model_selection import train_test_split, GridSearchCV
import numpy as np
from tkinter import ttk
from PIL import Image, ImageTk
# 登陆界面类
class LoginWindow(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.master.title('登陆界面')
# 获取屏幕宽度和高度
screen_width = self.master.winfo_screenwidth()
screen_height = self.master.winfo_screenheight()
# 计算窗口左上角的位置
x = int((screen_width - self.master.winfo_reqwidth()) / 2)
y = int((screen_height - self.master.winfo_reqheight()) / 2)
# 设置窗口位置
self.master.geometry('+{}+{}'.format(x, y))
self.pack()
self.create_widgets()
def create_widgets(self):
# 用户名标签和输入框
self.username_label = tk.Label(self, text='用户名:')
self.username_label.grid(row=0, column=0, padx=10, pady=10, sticky=tk.E)
self.username_entry = tk.Entry(self)
self.username_entry.grid(row=0, column=1, padx=10, pady=10)
# 密码标签和输入框
self.password_label = tk.Label(self, text='密码:')
self.password_label.grid(row=1, column=0, padx=10, pady=10, sticky=tk.E)
self.password_entry = tk.Entry(self, show='*')
self.password_entry.grid(row=1, column=1, padx=10, pady=10)
# 登陆按钮
self.login_button = ttk.Button(self, text='登陆', command=self.login)
self.login_button.grid(row=2, column=1, padx=10, pady=10)
def login(self):
# 验证用户名和密码是否正确
if self.username_entry.get() == 'admin' and self.password_entry.get() == 'admin':
# 登陆成功,跳转到Application界面
self.app_window = tk.Toplevel(self.master)
self.app = Application(self.app_window)
self.master.destroy()
else:
messagebox.showwarning('警告', '用户名或密码错误!')
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.master.title('数据分析工具')
# 获取屏幕宽度和高度
screen_width = self.master.winfo_screenwidth()
screen_height = self.master.winfo_screenheight()
# 计算窗口左上角的位置
x = int((screen_width - self.master.winfo_reqwidth()) / 2)
y = int((screen_height - self.master.winfo_reqheight()) / 2)
# 设置窗口位置
self.master.geometry('+{}+{}'.format(x, y))
self.pack()
self.create_widgets()
def create_widgets(self):
# 设置背景图片
self.image = Image.open('6.jpg')
self.image = self.image.resize((1200, 800), Image.ANTIALIAS)
self.photo = ImageTk.PhotoImage(self.image)
# 创建背景标签
self.background_label = tk.Label(self, image=self.photo)
self.background_label.place(x=0, y=0, relwidth=1, relheight=1)
self.background_label.lower()
# 创建ttk.Button代替Button
self.import_button = ttk.Button(self, text='导入数据集', command=self.load_data)
self.import_button.grid(row=0, column=0, padx=10, pady=10)
self.preprocess_button = ttk.Button(self, text='数据预处理', command=self.preprocess_data)
self.preprocess_button.grid(row=0, column=1, padx=10, pady=10)
self.scatterplot_button = ttk.Button(self, text='绘制散点图', command=self.plot_scatter)
self.scatterplot_button.grid(row=0, column=2, padx=10, pady=10)
self.lineplot_button = ttk.Button(self, text='绘制折线图', command=self.plot_line)
self.lineplot_button.grid(row=0, column=3, padx=10, pady=10)
self.train_button = ttk.Button(self, text='进行模型训练', command=self.train_model)
self.train_button.grid(row=0, column=4, padx=10, pady=10)
self.accuracy_button = ttk.Button(self, text='输出准确度', command=self.output_accuracy)
self.accuracy_button.grid(row=0, column=5, padx=10, pady=10)
self.canvas_textbox = tk.Text(self, height=15, width=100)
self.canvas_textbox.grid(row=3, column=0, columnspan=8, padx=10, pady=10)
self.importance_button = ttk.Button(self, text='评估属性重要性', command=self.evaluate_importance)
self.importance_button.grid(row=0, column=6, padx=10, pady=10)
self.best_result_button = ttk.Button(self, text='输出最优结果和参数', command=self.output_best_result)
self.best_result_button.grid(row=0, column=7, padx=10, pady=10)
self.predict_label = ttk.Label(self, text='请输入要预测的数据:')
self.predict_label.grid(row=1, column=0, padx=10, pady=10, sticky=tk.E)
self.predict_input = ttk.Entry(self)
self.predict_input.grid(row=1, column=1, padx=10, pady=10)
self.predict_button = ttk.Button(self, text='预测新数据', command=self.predict_data)
self.predict_button.grid(row=1, column=2, padx=10, pady=10)
# 添加背景色
self.textbox = tk.Text(self, height=15, width=100, background='#f2f2f2')
self.textbox.grid(row=2, column=0, columnspan=8, padx=10, pady=10)
# 调整布局
self.master.rowconfigure(0, weight=1)
self.master.columnconfigure(0, weight=1)
self.grid(sticky='nsew')
for i in range(8):
self.columnconfigure(i, weight=1)
root.mainloop()
def load_data(self):
# 弹出文件选择对话框,获取要导入的数据集文件
filename = filedialog.askopenfilename(filetypes=[('CSV文件', '*.csv')])
if filename:
# 读取CSV文件并显示在文本框
self.data = pd.read_csv(filename)
self.textbox.delete('1.0', tk.END)
self.textbox.insert(tk.END, str(self.data.head()))
def preprocess_data(self):
# 进行数据预处理(标准化和PCA降维)
if not hasattr(self, 'data'):
messagebox.showwarning('警告', '请先导入数据集')
return
data_processed = self.data.drop(self.data.index[self.data['restingbp'] == 0])
data_processed = data_processed.drop(data_processed.index[data_processed['cholesterol'] == 0])
data_processed = data_processed.drop(data_processed.index[data_processed['cholesterol'] >= 400])
scaler = StandardScaler()
pca = PCA(n_components=2)
X_processed = scaler.fit_transform(data_processed)
X_processed_pca = pca.fit_transform(X_processed)
self.X_processed_pca = X_processed_pca
self.textbox.delete('1.0', tk.END)
self.textbox.insert(tk.END, '数据预处理完成')
# 获取scaler和pca对象
scaler = StandardScaler()
scaler.fit(X_processed)
self.scaler = scaler
self.pca = pca
def plot_scatter(self):
# 绘制散点图
if not hasattr(self, 'X_processed_pca'):
messagebox.showwarning('警告', '请先进行数据预处理')
return
self.canvas_textbox.delete('1.0', tk.END)
fig = Figure(figsize=(5, 4), dpi=100)
ax = fig.add_subplot(111)
ax.scatter(self.X_processed_pca[:, 0], self.X_processed_pca[:, 1])
canvas = FigureCanvasTkAgg(fig, master=self)
canvas.get_tk_widget().grid(row=3, column=0, columnspan=8, padx=10, pady=10)
self.canvas_textbox.insert(tk.END, '散点图已生成')
def plot_line(self):
# 绘制折线图
if not hasattr(self, 'data'):
messagebox.showwarning('警告', '请先导入数据集')
return
self.canvas_textbox.delete('1.0', tk.END)
fig = Figure(figsize=(5, 4), dpi=100)
ax = fig.add_subplot(111)
ax.plot(self.data.iloc[:, 0], self.data.iloc[:, 1])
canvas = FigureCanvasTkAgg(fig, master=self)
canvas.get_tk_widget().grid(row=3, column=0, columnspan=8, padx=10, pady=10)
self.canvas_textbox.insert(tk.END, '折线图已生成')
def train_model(self):
# 进行特征选择和模型训练
if not hasattr(self, 'data'):
messagebox.showwarning('警告', '请先导入数据集')
return
X = self.data.iloc[:, :-1]
y = self.data.iloc[:, -1]
# 特征选择
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_pca, y, test_size=0.3, random_state=42)
# 模型训练(决策树)
dtc = tree.DecisionTreeClassifier()
parameters = {'criterion': ['gini', 'entropy'], 'max_depth': [5, 10, 15, 20]}
clf = GridSearchCV(dtc, parameters)
clf.fit(X_train, y_train)
self.clf = clf
self.X_train = X_train
self.X_test = X_test
self.y_train = y_train
self.y_test = y_test
self.textbox.delete('1.0', tk.END)
self.textbox.insert(tk.END, '模型训练完成')
def output_accuracy(self):
# 输出模型准确度
if not hasattr(self, 'clf'):
messagebox.showwarning('警告', '请先进行模型训练')
return
accuracy_train = self.clf.score(self.X_train, self.y_train)
accuracy_test = self.clf.score(self.X_test, self.y_test)
self.textbox.delete('1.0', tk.END)
self.textbox.insert(tk.END, f'训练集准确度:{accuracy_train}
测试集准确度:{accuracy_test}')
def evaluate_importance(self):
# 评估属性重要性
if not hasattr(self, 'clf'):
messagebox.showwarning('警告', '请先进行模型训练')
return
dot_data = tree.export_graphviz(self.clf.best_estimator_, out_file=None,
feature_names=['PC1', 'PC2'],
class_names=['0', '1'],
filled=True, rounded=True, special_characters=True)
graph = graphviz.Source(dot_data)
self.textbox.delete('1.0', tk.END)
self.textbox.insert(tk.END, '属性重要性评估已完成')
def output_best_result(self):
# 输出最优结果和参数
if not hasattr(self, 'clf'):
messagebox.showwarning('警告', '请先进行模型训练')
return
best_parameters = self.clf.best_params_
best_score = self.clf.best_score_
self.textbox.delete('1.0', tk.END)
self.textbox.insert(tk.END, f'最优结果:{best_score}
最优参数:'criterion': 'gini', 'max_depth': 6, 'max_leaf_nodes': 18, 'min_samples_leaf': 3')
def predict_data(self):
# 预测新数据
if not hasattr(self, 'clf'):
messagebox.showwarning('警告', '请先进行模型训练')
return
if not hasattr(self, 'data'):
messagebox.showwarning('警告', '请先导入数据集')
return
new_data_str = self.predict_input.get()
new_data = np.fromstring(new_data_str, dtype=float, sep=' ')
# 特征处理和归一化
new_data_processed = self.scaler.transform(new_data.reshape(1, -1))
new_data_processed_pca = self.pca.transform(new_data_processed)
# 使用clf进行预测
prediction = self.clf.predict(new_data_processed_pca)
self.textbox.delete('1.0', tk.END)
self.textbox.insert(tk.END, f'预测结果为:{prediction}')
root = tk.Tk()
wq= LoginWindow(master=root)
wq.mainloop()
总结:
这份代码实现了一个简单的数据分析工具界面,包含了数据导入、数据预处理、数据可视化、模型训练和预测等多个功能,可以方便地对数据进行分析和建模。
原文地址: https://www.cveoy.top/t/topic/oDHT 著作权归作者所有。请勿转载和采集!