Vibrant Data Navigator Python GUI
👤 Sharing: AI
import tkinter as tk
from tkinter import ttk
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import seaborn as sns
import io
from tkinter import filedialog, messagebox
class DataNavigator:
def __init__(self, master):
self.master = master
master.title("Vibrant Data Navigator")
master.geometry("1200x800")
self.data = None
self.filename = 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 as CSV", command=self.save_as_csv)
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 layout ---
self.paned_window = tk.PanedWindow(master, orient=tk.HORIZONTAL)
self.paned_window.pack(fill=tk.BOTH, expand=True)
# --- Left Frame (Data View) ---
self.left_frame = tk.Frame(self.paned_window, bd=2, relief=tk.SUNKEN)
self.paned_window.add(self.left_frame)
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, show="headings", height=20)
self.data_tree.pack(fill=tk.BOTH, expand=True)
self.scrollbar_x = tk.Scrollbar(self.left_frame, orient=tk.HORIZONTAL, command=self.data_tree.xview)
self.scrollbar_x.pack(fill=tk.X)
self.scrollbar_y = tk.Scrollbar(self.left_frame, orient=tk.VERTICAL, command=self.data_tree.yview)
self.scrollbar_y.pack(fill=tk.Y, side=tk.RIGHT)
self.data_tree.configure(xscrollcommand=self.scrollbar_x.set, yscrollcommand=self.scrollbar_y.set)
# --- Right Frame (Controls & Plots) ---
self.right_frame = tk.Frame(self.paned_window, bd=2, relief=tk.SUNKEN)
self.paned_window.add(self.right_frame)
self.control_label = tk.Label(self.right_frame, text="Data Analysis Controls")
self.control_label.pack(pady=5)
# --- Plot Type Selection ---
self.plot_type_label = tk.Label(self.right_frame, text="Plot Type:")
self.plot_type_label.pack()
self.plot_type = tk.StringVar(value="scatter") #default value
self.plot_options = ttk.Combobox(self.right_frame, textvariable=self.plot_type, values=["scatter", "histogram", "bar", "boxplot", "heatmap"], state="readonly")
self.plot_options.pack()
# --- Column Selection ---
self.x_column_label = tk.Label(self.right_frame, text="X Column:")
self.x_column_label.pack()
self.x_column = tk.StringVar()
self.x_column_dropdown = ttk.Combobox(self.right_frame, textvariable=self.x_column, state="readonly")
self.x_column_dropdown.pack()
self.y_column_label = tk.Label(self.right_frame, text="Y Column:")
self.y_column_label.pack()
self.y_column = tk.StringVar()
self.y_column_dropdown = ttk.Combobox(self.right_frame, textvariable=self.y_column, state="readonly")
self.y_column_dropdown.pack()
# --- Plot Button ---
self.plot_button = tk.Button(self.right_frame, text="Generate Plot", command=self.generate_plot)
self.plot_button.pack(pady=10)
# --- Plot Canvas ---
self.plot_canvas = tk.Canvas(self.right_frame, bg="white", height=400, width=500)
self.plot_canvas.pack(fill=tk.BOTH, expand=True)
# --- Info Button ---
self.info_button = tk.Button(self.right_frame, text="What does this program do?", command=self.show_details)
self.info_button.pack(pady=10)
def load_data(self):
self.filename = filedialog.askopenfilename(initialdir=".", title="Select a CSV file", filetypes=(("CSV files", "*.csv"), ("all files", "*")))
if self.filename:
try:
self.data = pd.read_csv(self.filename)
self.populate_treeview()
self.update_column_options()
except Exception as e:
messagebox.showerror("Error", f"Error loading data: {e}")
def save_as_csv(self):
if self.data is None:
messagebox.showerror("Error", "No data loaded to save.")
return
filename = filedialog.asksaveasfilename(defaultextension=".csv", filetypes=(("CSV files", "*.csv"), ("all files", "*")))
if filename:
try:
self.data.to_csv(filename, index=False)
messagebox.showinfo("Success", f"Data saved successfully to {filename}")
except Exception as e:
messagebox.showerror("Error", f"Error saving data: {e}")
def populate_treeview(self):
# Clear existing data
for item in self.data_tree.get_children():
self.data_tree.delete(item)
# Set up column headers
self.data_tree["column"] = list(self.data.columns)
self.data_tree["show"] = "headings"
for column in self.data_tree["column"]:
self.data_tree.heading(column, text=column)
self.data_tree.column(column, width=100)
# Insert data
for index, row in self.data.iterrows():
self.data_tree.insert("", "end", values=list(row))
def update_column_options(self):
if self.data is not None:
columns = list(self.data.columns)
self.x_column_dropdown['values'] = columns
self.y_column_dropdown['values'] = columns
def generate_plot(self):
if self.data is None:
messagebox.showerror("Error", "Please load data first.")
return
plot_type = self.plot_type.get()
x_col = self.x_column.get()
y_col = self.y_column.get()
if not x_col or not y_col:
messagebox.showerror("Error", "Please select X and Y columns.")
return
try:
# Clear previous plot
for item in self.plot_canvas.winfo_children():
item.destroy()
fig, ax = plt.subplots(figsize=(6, 4))
if plot_type == "scatter":
ax.scatter(self.data[x_col], self.data[y_col])
ax.set_xlabel(x_col)
ax.set_ylabel(y_col)
ax.set_title(f"Scatter Plot: {x_col} vs {y_col}")
elif plot_type == "histogram":
ax.hist(self.data[x_col], bins=20)
ax.set_xlabel(x_col)
ax.set_ylabel("Frequency")
ax.set_title(f"Histogram of {x_col}")
elif plot_type == "bar":
# Ensure y_col contains counts or values for bars
ax.bar(self.data[x_col], self.data[y_col])
ax.set_xlabel(x_col)
ax.set_ylabel(y_col)
ax.set_title(f"Bar Chart: {x_col} vs {y_col}")
plt.xticks(rotation=45, ha='right') #rotate x axis labels
elif plot_type == "boxplot":
ax.boxplot(self.data[x_col])
ax.set_ylabel(x_col)
ax.set_title(f"Boxplot of {x_col}")
elif plot_type == "heatmap":
# Example: Correlation heatmap (requires numeric data)
correlation_matrix = self.data[[x_col, y_col]].corr()
sns.heatmap(correlation_matrix, annot=True, cmap="coolwarm", ax=ax)
ax.set_title(f"Heatmap: Correlation between {x_col} and {y_col}")
fig.tight_layout()
canvas = FigureCanvasTkAgg(fig, master=self.plot_canvas)
canvas.draw()
canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)
except Exception as e:
messagebox.showerror("Error", f"Error generating plot: {e}")
def show_details(self):
messagebox.showinfo("Program Details", "This program, the Vibrant Data Navigator, allows you to load CSV data, view it in a table, and generate various types of plots based on selected columns. You can create scatter plots, histograms, bar charts, boxplots, and heatmaps to explore your data visually. The program includes a menu for opening files, saving the data as CSV, and an 'About' section with information about the application. It is designed to be a versatile tool for basic data exploration and visualization.")
def show_about(self):
messagebox.showinfo("About", "Vibrant Data Navigator\nVersion 1.0\nCreated for versatile data exploration and visualization.\nPowered by Tkinter, Pandas, Matplotlib, and Seaborn.")
root = tk.Tk()
navigator = DataNavigator(root)
root.mainloop()
👁️ Viewed: 79
Comments