Python数据分析工具 - 基于Tkinter和Matplotlib的图形化界面

这份代码实现了一个简单的数据分析工具界面,包含了数据导入、数据预处理、数据可视化、模型训练和预测等多个功能,可以方便地对数据进行分析和建模。

代码主要分为两个类:LoginWindowApplication

1. 登陆界面 (LoginWindow)

登陆界面包含用户名和密码输入框以及登陆按钮,当用户输入正确的用户名和密码时,会跳转到 Application 界面。

2. 数据分析工具界面 (Application)

数据分析工具界面包含了导入数据、数据预处理、数据可视化、模型训练和预测等功能。具体实现如下:

(1) 导入数据 (load_data): 该函数会弹出文件选择对话框,获取要导入的数据集文件,并读取CSV文件并显示在文本框。

(2) 数据预处理 (preprocess_data): 该函数会进行数据预处理(标准化和PCA降维),并获取scalerpca 对象。

(3) 绘制散点图 (plot_scatter): 该函数会绘制散点图,并在图形化界面中显示。

(4) 绘制折线图 (plot_line): 该函数会绘制折线图,并在图形化界面中显示。

(5) 模型训练 (train_model): 该函数会进行特征选择和模型训练(决策树),并获取clfX_trainX_testy_trainy_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()

总结:

这份代码实现了一个简单的数据分析工具界面,包含了数据导入、数据预处理、数据可视化、模型训练和预测等多个功能,可以方便地对数据进行分析和建模。

Python数据分析工具 - 基于Tkinter和Matplotlib的图形化界面

原文地址: https://www.cveoy.top/t/topic/oDHT 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录