EtherealDataSculptor Python GUI
👤 Sharing: AI
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import seaborn as sns
import io
from PIL import Image, ImageTk
class DataSculptorApp:
def __init__(self, root):
self.root = root
self.root.title("EtherealDataSculptor")
self.root.geometry("1000x700")
self.notebook = ttk.Notebook(root)
self.notebook.pack(expand=True, fill="both")
self.create_data_tab()
self.create_visualization_tab()
self.create_analysis_tab()
self.create_settings_tab()
self.data = None
self.current_file_path = None
def create_data_tab(self):
self.data_tab = ttk.Frame(self.notebook)
self.notebook.add(self.data_tab, text="Data")
self.data_frame = tk.Frame(self.data_tab)
self.data_frame.pack(expand=True, fill="both", padx=10, pady=10)
self.data_table = ttk.Treeview(self.data_frame, columns=())
self.data_table.pack(expand=True, fill="both", side=tk.LEFT)
self.scrollbar = ttk.Scrollbar(self.data_frame, orient=tk.VERTICAL, command=self.data_table.yview)
self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.data_table['yscrollcommand'] = self.scrollbar.set
self.button_frame = tk.Frame(self.data_tab)
self.button_frame.pack(pady=5)
self.load_button = ttk.Button(self.button_frame, text="Load Data", command=self.load_data)
self.load_button.pack(side=tk.LEFT, padx=5)
self.save_button = ttk.Button(self.button_frame, text="Save Data", command=self.save_data)
self.save_button.pack(side=tk.LEFT, padx=5)
self.clear_button = ttk.Button(self.button_frame, text="Clear Data", command=self.clear_data)
self.clear_button.pack(side=tk.LEFT, padx=5)
self.details_button = ttk.Button(self.button_frame, text="Details", command=self.show_data_tab_details)
self.details_button.pack(side=tk.LEFT, padx=5)
def create_visualization_tab(self):
self.visualization_tab = ttk.Frame(self.notebook)
self.notebook.add(self.visualization_tab, text="Visualization")
self.visualization_frame = tk.Frame(self.visualization_tab)
self.visualization_frame.pack(expand=True, fill="both", padx=10, pady=10)
self.plot_frame = tk.Frame(self.visualization_frame)
self.plot_frame.pack(expand=True, fill="both", side=tk.LEFT)
self.visualization_controls = tk.Frame(self.visualization_frame)
self.visualization_controls.pack(side=tk.RIGHT, fill=tk.Y, padx=10)
self.plot_type_label = ttk.Label(self.visualization_controls, text="Plot Type:")
self.plot_type_label.pack()
self.plot_type_options = ["Scatter", "Line", "Bar", "Histogram", "Boxplot", "Pie"]
self.plot_type_var = tk.StringVar(value=self.plot_type_options[0])
self.plot_type_dropdown = ttk.Combobox(self.visualization_controls, textvariable=self.plot_type_var, values=self.plot_type_options, state="readonly")
self.plot_type_dropdown.pack()
self.x_axis_label = ttk.Label(self.visualization_controls, text="X Axis:")
self.x_axis_label.pack()
self.x_axis_var = tk.StringVar()
self.x_axis_dropdown = ttk.Combobox(self.visualization_controls, textvariable=self.x_axis_var, values=[], state="readonly")
self.x_axis_dropdown.pack()
self.y_axis_label = ttk.Label(self.visualization_controls, text="Y Axis:")
self.y_axis_label.pack()
self.y_axis_var = tk.StringVar()
self.y_axis_dropdown = ttk.Combobox(self.visualization_controls, textvariable=self.y_axis_var, values=[], state="readonly")
self.y_axis_dropdown.pack()
self.generate_button = ttk.Button(self.visualization_controls, text="Generate Plot", command=self.generate_plot)
self.generate_button.pack(pady=10)
self.canvas = None # Initialize canvas attribute
self.toolbar_frame = tk.Frame(self.visualization_frame) # Frame for toolbar
self.toolbar_frame.pack(side=tk.BOTTOM, fill=tk.X)
self.details_button = ttk.Button(self.visualization_controls, text="Details", command=self.show_visualization_tab_details)
self.details_button.pack(pady=10)
def create_analysis_tab(self):
self.analysis_tab = ttk.Frame(self.notebook)
self.notebook.add(self.analysis_tab, text="Analysis")
self.analysis_frame = tk.Frame(self.analysis_tab)
self.analysis_frame.pack(expand=True, fill="both", padx=10, pady=10)
self.analysis_options_frame = tk.Frame(self.analysis_frame)
self.analysis_options_frame.pack(side=tk.LEFT, fill=tk.Y, padx=10)
self.analysis_type_label = ttk.Label(self.analysis_options_frame, text="Analysis Type:")
self.analysis_type_label.pack()
self.analysis_type_options = ["Descriptive Statistics", "Correlation Matrix", "Regression Analysis"]
self.analysis_type_var = tk.StringVar(value=self.analysis_type_options[0])
self.analysis_type_dropdown = ttk.Combobox(self.analysis_options_frame, textvariable=self.analysis_type_var, values=self.analysis_type_options, state="readonly")
self.analysis_type_dropdown.pack()
self.run_analysis_button = ttk.Button(self.analysis_options_frame, text="Run Analysis", command=self.run_analysis)
self.run_analysis_button.pack(pady=10)
self.analysis_output = tk.Text(self.analysis_frame, wrap=tk.WORD)
self.analysis_output.pack(expand=True, fill="both", side=tk.RIGHT)
self.details_button = ttk.Button(self.analysis_options_frame, text="Details", command=self.show_analysis_tab_details)
self.details_button.pack(pady=10)
def create_settings_tab(self):
self.settings_tab = ttk.Frame(self.notebook)
self.notebook.add(self.settings_tab, text="Settings")
self.settings_frame = tk.Frame(self.settings_tab)
self.settings_frame.pack(expand=True, fill="both", padx=10, pady=10)
self.theme_label = ttk.Label(self.settings_frame, text="Theme:")
self.theme_label.pack()
self.theme_options = ["Default", "Darkly", "Flatly", "Journal", "Litera", "Lumen", "Minty", "Pulse", "Sandstone", "Simplex", "Sketchy", "Spacelab", "United", "Yeti"]
self.theme_var = tk.StringVar(value="Default")
self.theme_dropdown = ttk.Combobox(self.settings_frame, textvariable=self.theme_var, values=self.theme_options, state="readonly")
self.theme_dropdown.pack()
self.theme_dropdown.bind("<<ComboboxSelected>>", self.apply_theme)
self.font_label = ttk.Label(self.settings_frame, text="Font Size:")
self.font_label.pack()
self.font_size_var = tk.IntVar(value=12)
self.font_size_spinbox = tk.Spinbox(self.settings_frame, from_=8, to=24, textvariable=self.font_size_var)
self.font_size_spinbox.pack()
self.font_size_spinbox.bind("<ButtonRelease-1>", self.apply_font_size)
self.details_button = ttk.Button(self.settings_frame, text="Details", command=self.show_settings_tab_details)
self.details_button.pack(pady=10)
def load_data(self):
file_path = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv"), ("Excel Files", "*.xlsx")])
if file_path:
try:
if file_path.endswith(".csv"):
self.data = pd.read_csv(file_path)
elif file_path.endswith(".xlsx"):
self.data = pd.read_excel(file_path)
else:
messagebox.showerror("Error", "Unsupported file format. Please select a CSV or Excel file.")
return
self.current_file_path = file_path
self.populate_data_table()
self.update_dropdown_options()
messagebox.showinfo("Success", "Data loaded successfully!")
except Exception as e:
messagebox.showerror("Error", f"Failed to load data: {e}")
def save_data(self):
if self.data is None:
messagebox.showinfo("Info", "No data loaded to save.")
return
file_path = filedialog.asksaveasfilename(defaultextension=".csv", filetypes=[("CSV Files", "*.csv")])
if file_path:
try:
self.data.to_csv(file_path, index=False)
messagebox.showinfo("Success", "Data saved successfully!")
except Exception as e:
messagebox.showerror("Error", f"Failed to save data: {e}")
def clear_data(self):
self.data = None
for item in self.data_table.get_children():
self.data_table.delete(item)
self.x_axis_dropdown['values'] = []
self.y_axis_dropdown['values'] = []
self.x_axis_var.set('')
self.y_axis_var.set('')
self.current_file_path = None
messagebox.showinfo("Info", "Data cleared.")
def populate_data_table(self):
for item in self.data_table.get_children():
self.data_table.delete(item)
if self.data is not None:
self.data_table['columns'] = list(self.data.columns)
for col in self.data.columns:
self.data_table.heading(col, text=col)
self.data_table.column(col, width=100)
for index, row in self.data.iterrows():
self.data_table.insert("", tk.END, values=list(row))
def update_dropdown_options(self):
if self.data is not None:
columns = list(self.data.columns)
self.x_axis_dropdown['values'] = columns
self.y_axis_dropdown['values'] = columns
if columns:
self.x_axis_var.set(columns[0])
self.y_axis_var.set(columns[0] if len(columns) > 1 else columns[0])
def generate_plot(self):
if self.data is None:
messagebox.showinfo("Info", "Load data first.")
return
plot_type = self.plot_type_var.get().lower()
x_axis = self.x_axis_var.get()
y_axis = self.y_axis_var.get()
if not x_axis or not y_axis:
messagebox.showerror("Error", "Please select X and Y axes.")
return
try:
plt.clf()
if plot_type == "scatter":
sns.scatterplot(x=x_axis, y=y_axis, data=self.data)
elif plot_type == "line":
sns.lineplot(x=x_axis, y=y_axis, data=self.data)
elif plot_type == "bar":
sns.barplot(x=x_axis, y=y_axis, data=self.data)
elif plot_type == "histogram":
sns.histplot(self.data[x_axis])
elif plot_type == "boxplot":
sns.boxplot(x=self.data[x_axis], y=self.data[y_axis])
elif plot_type == "pie":
plt.pie(self.data[y_axis], labels=self.data[x_axis], autopct='%1.1f%%')
else:
messagebox.showerror("Error", "Invalid plot type.")
return
plt.title(f"{plot_type.capitalize()} Plot of {y_axis} vs {x_axis}")
plt.xlabel(x_axis)
plt.ylabel(y_axis)
# Convert plot to Tkinter-compatible image
buf = io.BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
img = Image.open(buf)
self.tk_img = ImageTk.PhotoImage(img)
# Display image in Tkinter label
if hasattr(self, 'image_label'):
self.image_label.destroy()
self.image_label = tk.Label(self.plot_frame, image=self.tk_img)
self.image_label.image = self.tk_img # keep a reference!
self.image_label.pack(fill="both", expand=True)
except Exception as e:
messagebox.showerror("Error", f"Failed to generate plot: {e}")
def run_analysis(self):
if self.data is None:
messagebox.showinfo("Info", "Load data first.")
return
analysis_type = self.analysis_type_var.get()
try:
if analysis_type == "Descriptive Statistics":
output = self.data.describe().to_string()
elif analysis_type == "Correlation Matrix":
output = self.data.corr().to_string()
elif analysis_type == "Regression Analysis":
messagebox.showinfo("Info", "Regression Analysis requires specifying dependent and independent variables. Feature is under development.")
return
else:
messagebox.showerror("Error", "Invalid analysis type.")
return
self.analysis_output.delete("1.0", tk.END)
self.analysis_output.insert(tk.END, output)
except Exception as e:
messagebox.showerror("Error", f"Failed to run analysis: {e}")
def apply_theme(self, event=None):
selected_theme = self.theme_var.get().lower()
if selected_theme == "default":
self.root.tk.call("ttk::style", "theme", "use", "default")
else:
try:
self.root.tk.call("ttk::style", "theme", "use", selected_theme)
except tk.TclError:
messagebox.showerror("Error", f"Theme '{selected_theme}' not found.")
self.theme_var.set("Default")
self.root.tk.call("ttk::style", "theme", "use", "default")
def apply_font_size(self, event=None):
font_size = self.font_size_var.get()
style = ttk.Style()
style.configure("TLabel", font=("Arial", font_size))
style.configure("TButton", font=("Arial", font_size))
style.configure("TCombobox", font=("Arial", font_size))
style.configure("Treeview", font=("Arial", font_size))
style.configure("TNotebook.Tab", font=("Arial", font_size))
self.analysis_output.configure(font=("Arial", font_size))
def show_data_tab_details(self):
messagebox.showinfo("Data Tab Details", "The Data tab allows you to load, save, and clear data. Supported formats are CSV and Excel (.xlsx). Loaded data is displayed in a table format.")
def show_visualization_tab_details(self):
messagebox.showinfo("Visualization Tab Details", "The Visualization tab enables you to create various types of plots from the loaded data. You can select the plot type, X-axis, and Y-axis. The generated plot is displayed in the plot area.")
def show_analysis_tab_details(self):
messagebox.showinfo("Analysis Tab Details", "The Analysis tab provides basic data analysis functionalities such as descriptive statistics and correlation matrix. You can select the analysis type and view the output in the text area.")
def show_settings_tab_details(self):
messagebox.showinfo("Settings Tab Details", "The Settings tab allows you to customize the application's appearance. You can select a theme and adjust the font size for various elements.")
root = tk.Tk()
app = DataSculptorApp(root)
root.mainloop()
👁️ Viewed: 9
Comments