Whimsical Data Sculptor 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 random
class DataSculptor:
def __init__(self, master):
self.master = master
master.title("Whimsical Data Sculptor")
# --- Data Storage --- #
self.data = None
self.filepath = None
# --- Styling --- #
self.font_family = "Arial, sans-serif"
self.bg_color = "#f0f0f0"
self.button_color = "#4CAF50"
self.text_color = "#333333"
# --- UI Elements --- #
self.create_widgets()
def create_widgets(self):
# --- Main Frames --- #
self.input_frame = ttk.Frame(self.master, padding=10)
self.input_frame.pack(pady=10, fill=tk.X)
self.analysis_frame = ttk.Frame(self.master, padding=10)
self.analysis_frame.pack(pady=10, fill=tk.BOTH, expand=True)
# --- Input Frame Widgets --- #
self.load_button = ttk.Button(self.input_frame, text="Load Data (CSV, Excel)", command=self.load_data, style="Accent.TButton")
self.load_button.pack(side=tk.LEFT, padx=5)
self.view_button = ttk.Button(self.input_frame, text="View Data", command=self.view_data, state=tk.DISABLED)
self.view_button.pack(side=tk.LEFT, padx=5)
self.analyze_button = ttk.Button(self.input_frame, text="Analyze Data", command=self.analyze_data, state=tk.DISABLED)
self.analyze_button.pack(side=tk.LEFT, padx=5)
# --- Styling the buttons --- #
style = ttk.Style()
style.configure("Accent.TButton", foreground=self.text_color, background=self.button_color, font=(self.font_family, 10))
# --- Analysis Frame Widgets --- #
self.notebook = ttk.Notebook(self.analysis_frame)
self.notebook.pack(fill=tk.BOTH, expand=True)
self.summary_tab = ttk.Frame(self.notebook)
self.visualization_tab = ttk.Frame(self.notebook)
self.custom_analysis_tab = ttk.Frame(self.notebook)
self.notebook.add(self.summary_tab, text="Data Summary")
self.notebook.add(self.visualization_tab, text="Data Visualization")
self.notebook.add(self.custom_analysis_tab, text="Custom Analysis")
# --- Summary Tab --- #
self.summary_text = tk.Text(self.summary_tab, wrap=tk.WORD, height=10, width=80, font=(self.font_family, 10))
self.summary_text.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
# --- Visualization Tab --- #
self.figure = plt.Figure(figsize=(8, 6), dpi=100)
self.canvas = FigureCanvasTkAgg(self.figure, master=self.visualization_tab)
self.canvas.get_tk_widget().pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
self.visualization_options_frame = ttk.Frame(self.visualization_tab)
self.visualization_options_frame.pack(pady=5)
self.plot_type_label = ttk.Label(self.visualization_options_frame, text="Plot Type:", font=(self.font_family, 10))
self.plot_type_label.pack(side=tk.LEFT, padx=5)
self.plot_type_var = tk.StringVar(value="scatter")
self.plot_type_dropdown = ttk.Combobox(self.visualization_options_frame, textvariable=self.plot_type_var, values=["scatter", "hist", "box", "violin", "bar"], state="readonly")
self.plot_type_dropdown.pack(side=tk.LEFT, padx=5)
self.plot_type_dropdown.bind("<<ComboboxSelected>>", self.update_visualization)
self.x_axis_label = ttk.Label(self.visualization_options_frame, text="X Axis:", font=(self.font_family, 10))
self.x_axis_label.pack(side=tk.LEFT, padx=5)
self.x_axis_var = tk.StringVar()
self.x_axis_dropdown = ttk.Combobox(self.visualization_options_frame, textvariable=self.x_axis_var, values=[], state="readonly")
self.x_axis_dropdown.pack(side=tk.LEFT, padx=5)
self.x_axis_dropdown.bind("<<ComboboxSelected>>", self.update_visualization)
self.y_axis_label = ttk.Label(self.visualization_options_frame, text="Y Axis:", font=(self.font_family, 10))
self.y_axis_label.pack(side=tk.LEFT, padx=5)
self.y_axis_var = tk.StringVar()
self.y_axis_dropdown = ttk.Combobox(self.visualization_options_frame, textvariable=self.y_axis_var, values=[], state="readonly")
self.y_axis_dropdown.pack(side=tk.LEFT, padx=5)
self.y_axis_dropdown.bind("<<ComboboxSelected>>", self.update_visualization)
# --- Custom Analysis Tab --- #
self.custom_analysis_text = tk.Text(self.custom_analysis_tab, wrap=tk.WORD, height=10, width=80, font=(self.font_family, 10))
self.custom_analysis_text.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
self.run_analysis_button = ttk.Button(self.custom_analysis_tab, text="Run Analysis", command=self.run_custom_analysis)
self.run_analysis_button.pack(pady=5)
# --- Status Bar --- #
self.status_var = tk.StringVar(value="Ready")
self.status_bar = ttk.Label(self.master, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W, font=(self.font_family, 8))
self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)
def load_data(self):
self.filepath = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv"), ("Excel files", "*.xlsx;*.xls")])
if self.filepath:
try:
if self.filepath.endswith(('.xlsx', '.xls')):
self.data = pd.read_excel(self.filepath)
else:
self.data = pd.read_csv(self.filepath)
self.status_var.set(f"Data loaded from: {self.filepath}")
self.view_button["state"] = tk.NORMAL
self.analyze_button["state"] = tk.NORMAL
# Update dropdown options
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]) # Set a default value
if len(columns) > 1:
self.y_axis_var.set(columns[1])
self.update_visualization()
except Exception as e:
messagebox.showerror("Error", f"Failed to load data: {e}")
self.status_var.set("Error loading data")
def view_data(self):
if self.data is not None:
try:
# Open in a new window
view_window = tk.Toplevel(self.master)
view_window.title("Data View")
tree = ttk.Treeview(view_window, columns=list(self.data.columns), show='headings')
for col in self.data.columns:
tree.heading(col, text=col)
tree.column(col, width=100)
for index, row in self.data.iterrows():
tree.insert('', tk.END, values=list(row))
tree.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
except Exception as e:
messagebox.showerror("Error", f"Error displaying data: {e}")
else:
messagebox.showinfo("Info", "No data loaded.")
def analyze_data(self):
if self.data is not None:
try:
# Generate summary statistics
summary = self.data.describe().to_string()
self.summary_text.delete("1.0", tk.END)
self.summary_text.insert(tk.END, summary)
# Display basic info
info = self.data.info(verbose=False, memory_usage='deep').to_string()
self.summary_text.insert(tk.END, "\n\nData Info:\n")
self.summary_text.insert(tk.END, info)
self.status_var.set("Data analysis complete.")
except Exception as e:
messagebox.showerror("Error", f"Error analyzing data: {e}")
self.status_var.set("Error analyzing data")
else:
messagebox.showinfo("Info", "No data loaded.")
def update_visualization(self, event=None):
if self.data is not None:
try:
self.figure.clear()
ax = self.figure.add_subplot(111)
plot_type = self.plot_type_var.get()
x_col = self.x_axis_var.get()
y_col = self.y_axis_var.get()
if plot_type == "scatter":
ax.scatter(self.data[x_col], self.data[y_col])
ax.set_xlabel(x_col)
ax.set_ylabel(y_col)
elif plot_type == "hist":
self.data[x_col].hist(ax=ax)
ax.set_xlabel(x_col)
elif plot_type == "box":
sns.boxplot(x=self.data[x_col], ax=ax)
ax.set_xlabel(x_col)
elif plot_type == "violin":
sns.violinplot(x=self.data[x_col], ax=ax)
ax.set_xlabel(x_col)
elif plot_type == "bar":
self.data[x_col].value_counts().plot(kind='bar', ax=ax)
ax.set_xlabel(x_col)
ax.set_title(f"{plot_type.capitalize()} Plot of {x_col} vs {y_col if plot_type == 'scatter' else ''}")
self.canvas.draw()
except Exception as e:
messagebox.showerror("Error", f"Error creating visualization: {e}")
else:
messagebox.showinfo("Info", "No data loaded.")
def run_custom_analysis(self):
if self.data is not None:
try:
code = self.custom_analysis_text.get("1.0", tk.END)
# --- Security Warning --- #
messagebox.showwarning("Warning", "Executing arbitrary code can be dangerous. Proceed with caution!")
# --- Execute Code --- #
local_vars = {"df": self.data, "pd": pd, "np": pd.np}
try:
exec(code, globals(), local_vars)
messagebox.showinfo("Success", "Custom analysis executed successfully.")
except Exception as e:
messagebox.showerror("Error", f"Error executing custom analysis: {e}")
except Exception as e:
messagebox.showerror("Error", f"Error running custom analysis: {e}")
else:
messagebox.showinfo("Info", "No data loaded.")
root = tk.Tk()
root.geometry("800x600")
app = DataSculptor(root)
root.mainloop()
👁️ Viewed: 7
Comments