Zephyr Data Weaver 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 random
class DataWeaverApp:
def __init__(self, master):
self.master = master
master.title("Zephyr Data Weaver")
master.geometry("800x600")
self.data = None
self.filepath = None
# --- Menu Bar ---
self.menubar = tk.Menu(master)
filemenu = tk.Menu(self.menubar, tearoff=0)
filemenu.add_command(label="Open", command=self.load_data)
filemenu.add_command(label="Save", command=self.save_data)
filemenu.add_separator()
filemenu.add_command(label="Exit", command=master.quit)
self.menubar.add_cascade(label="File", menu=filemenu)
helpmenu = tk.Menu(self.menubar, tearoff=0)
helpmenu.add_command(label="About", command=self.show_about)
self.menubar.add_cascade(label="Help", menu=helpmenu)
master.config(menu=self.menubar)
# --- PanedWindow for layout ---
self.paned_window = ttk.PanedWindow(master, orient=tk.HORIZONTAL)
self.paned_window.pack(fill=tk.BOTH, expand=True)
# --- Left Frame (Data Display) ---
self.left_frame = tk.Frame(self.paned_window, bd=2, relief=tk.SUNKEN)
self.paned_window.add(self.left_frame, weight=1)
self.data_label = tk.Label(self.left_frame, text="Data Preview:")
self.data_label.pack(pady=5)
self.data_tree = ttk.Treeview(self.left_frame, columns=(), show='headings')
self.data_tree.pack(fill=tk.BOTH, expand=True)
self.x_scrollbar = ttk.Scrollbar(self.left_frame, orient='horizontal', command=self.data_tree.xview)
self.y_scrollbar = ttk.Scrollbar(self.left_frame, orient='vertical', command=self.data_tree.yview)
self.data_tree.configure(xscrollcommand=self.x_scrollbar.set, yscrollcommand=self.y_scrollbar.set)
self.x_scrollbar.pack(side='bottom', fill='x')
self.y_scrollbar.pack(side='right', fill='y')
# --- Right Frame (Operations) ---
self.right_frame = tk.Frame(self.paned_window, bd=2, relief=tk.SUNKEN)
self.paned_window.add(self.right_frame, weight=1)
self.operations_label = tk.Label(self.right_frame, text="Data Operations:")
self.operations_label.pack(pady=5)
self.summary_button = tk.Button(self.right_frame, text="Show Summary", command=self.show_summary)
self.summary_button.pack(pady=5, fill=tk.X)
self.plot_button = tk.Button(self.right_frame, text="Create Plot", command=self.create_plot)
self.plot_button.pack(pady=5, fill=tk.X)
self.filter_label = tk.Label(self.right_frame, text="Filter Data:")
self.filter_label.pack(pady=5)
self.filter_entry = tk.Entry(self.right_frame)
self.filter_entry.pack(pady=2, fill=tk.X)
self.filter_button = tk.Button(self.right_frame, text="Apply Filter", command=self.apply_filter)
self.filter_button.pack(pady=5, fill=tk.X)
# --- Detail Button (Hidden at first) ---
self.detail_button = tk.Button(self.right_frame, text="Details", command=self.show_details)
self.detail_button.pack(pady=5, fill=tk.X)
self.detail_button.pack_forget()
def load_data(self):
self.filepath = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv"), ("Excel Files", "*.xlsx")])
if self.filepath:
try:
if self.filepath.endswith(".csv"):
self.data = pd.read_csv(self.filepath)
else:
self.data = pd.read_excel(self.filepath)
self.populate_treeview()
self.detail_button.pack(pady=5, fill=tk.X) # Show detail button when file is loaded.
except Exception as e:
messagebox.showerror("Error", f"Could not load data: {e}")
def save_data(self):
if self.data is None:
messagebox.showinfo("Info", "No data to save.")
return
filepath = filedialog.asksaveasfilename(defaultextension=".csv", filetypes=[("CSV Files", "*.csv")])
if filepath:
try:
self.data.to_csv(filepath, index=False)
messagebox.showinfo("Info", "Data saved successfully!")
except Exception as e:
messagebox.showerror("Error", f"Could not save data: {e}")
def populate_treeview(self):
for item in self.data_tree.get_children():
self.data_tree.delete(item)
self.data_tree['columns'] = list(self.data.columns)
for col in self.data.columns:
self.data_tree.heading(col, text=col)
self.data_tree.column(col, width=100)
for index, row in self.data.iterrows():
self.data_tree.insert('', 'end', values=list(row))
def show_summary(self):
if self.data is None:
messagebox.showinfo("Info", "Load data first.")
return
summary = self.data.describe()
summary_window = tk.Toplevel(self.master)
summary_window.title("Data Summary")
summary_text = tk.Text(summary_window, height=20, width=80)
summary_text.pack(padx=10, pady=10)
summary_text.insert(tk.END, summary.to_string())
summary_text.config(state=tk.DISABLED)
def create_plot(self):
if self.data is None:
messagebox.showinfo("Info", "Load data first.")
return
plot_window = tk.Toplevel(self.master)
plot_window.title("Data Plot")
# Choose columns for plotting
columns = list(self.data.columns)
if len(columns) < 2:
messagebox.showinfo("Info", "Data needs at least 2 columns to create a plot.")
return
x_col = tk.StringVar(plot_window)
y_col = tk.StringVar(plot_window)
x_col.set(columns[0]) # Default values
y_col.set(columns[1])
x_label = tk.Label(plot_window, text="X-Axis Column:")
x_label.pack()
x_dropdown = tk.OptionMenu(plot_window, x_col, *columns)
x_dropdown.pack()
y_label = tk.Label(plot_window, text="Y-Axis Column:")
y_label.pack()
y_dropdown = tk.OptionMenu(plot_window, y_col, *columns)
y_dropdown.pack()
def plot_data():
try:
x = self.data[x_col.get()]
y = self.data[y_col.get()]
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y)
ax.set_xlabel(x_col.get())
ax.set_ylabel(y_col.get())
ax.set_title(f"{y_col.get()} vs {x_col.get()}")
ax.grid(True)
canvas = FigureCanvasTkAgg(fig, master=plot_window)
canvas.draw()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
except KeyError:
messagebox.showerror("Error", "Invalid column selected.")
except Exception as e:
messagebox.showerror("Error", f"Could not create plot: {e}")
plot_button = tk.Button(plot_window, text="Plot", command=plot_data)
plot_button.pack(pady=10)
def apply_filter(self):
if self.data is None:
messagebox.showinfo("Info", "Load data first.")
return
filter_expression = self.filter_entry.get()
try:
# Warning: Be very careful using eval. Sanitize user input carefully in a real application!
filtered_data = self.data.query(filter_expression)
self.data = filtered_data # Update the data
self.populate_treeview()
except Exception as e:
messagebox.showerror("Error", f"Invalid filter expression: {e}")
def show_details(self):
details_window = tk.Toplevel(self.master)
details_window.title("Program Details")
details_text = tk.Text(details_window, height=20, width=80)
details_text.pack(padx=10, pady=10)
details_text.insert(tk.END, "Zephyr Data Weaver is a versatile data analysis tool designed for ease of use and powerful functionality. It allows users to load, visualize, filter, and summarize data from CSV and Excel files. Key features include interactive data display using a Treeview, summary statistics generation, customizable plotting capabilities, and a query-based filtering system. The application is built with Tkinter to provide a cross-platform GUI experience.")
details_text.config(state=tk.DISABLED)
def show_about(self):
messagebox.showinfo("About Zephyr Data Weaver", "A powerful data analysis tool. Created for showcasing Python GUI capabilities.")
root = tk.Tk()
app = DataWeaverApp(root)
root.mainloop()
👁️ Viewed: 12
Comments