123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- import customtkinter as ctk
- import pandas as pd
- import matplotlib.pyplot as plt
- import numpy as np
- from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
- from tkinter import filedialog
- # Function to load data from file
- def load_data():
- filename = filedialog.askopenfilename(title="Select CSV file", filetypes=(("CSV files", "*.csv"), ("All files", "*.*")))
- return pd.read_csv(filename)
- # Function to update data
- def update_data():
- global data
- data = load_data()
- update_plot(start_slider.get(), end_slider.get())
- # Function to update plot based on slider values
- def update_plot(start_time, end_time):
- filtered_data = data[(data["Timestamp"] >= start_time) & (data["Timestamp"] <= end_time)]
- ax1.clear()
- ax1.plot(filtered_data["Timestamp"], filtered_data["Value"])
- ax1.set_title("Time Domain")
- ax1.set_xlabel("Timestamp")
- ax1.set_ylabel("Value")
- # Remove DC offset
- data_without_dc = filtered_data["Value"] - filtered_data["Value"].mean()
- # Perform Fourier analysis
- fft_values = np.fft.fft(data_without_dc)
- frequencies = np.fft.fftfreq(len(filtered_data), d=1 / sampling_rate)
- amplitudes = np.abs(fft_values)
- # Consider only positive frequencies
- positive_frequencies = frequencies[:len(frequencies)//2]
- positive_amplitudes = amplitudes[:len(frequencies)//2]
- ax2.clear()
- ax2.plot(positive_frequencies, positive_amplitudes)
- ax2.set_title("Frequency Domain")
- ax2.set_xlabel("Frequency (Hz)")
- ax2.set_ylabel("Amplitude")
- canvas.draw()
- # Create the main CustomTkinter window
- root = ctk.CTk()
- root.title("CSV Plot with Two Sliders")
- # Set appearance mode (optional)
- ctk.set_appearance_mode("dark") # Choose between "dark", "light", or "system"
- # Create matplotlib figure and axes
- fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 6))
- canvas = FigureCanvasTkAgg(fig, master=root)
- canvas.get_tk_widget().pack(side=ctk.LEFT, fill=ctk.BOTH, expand=True)
- # Function to initialize the plot
- def init_plot():
- global data
- global sampling_rate
- data = load_data()
- # Read the CSV file and extract timestamps
- timestamps = data["Timestamp"].tolist()
- # Calculate time differences
- time_diffs = [timestamps[i + 1] - timestamps[i] for i in range(len(timestamps) - 1)]
- # Calculate average time difference
- average_time_diff = sum(time_diffs) / len(time_diffs)
- # Sampling rate is the reciprocal of the average time difference
- sampling_rate = 1 / average_time_diff
- print("Sampling rate:", sampling_rate, "Hz")
- # Load only the last 10000 data points
- data = data.tail(10000)
- # Plot the initial data
- ax1.plot(data["Timestamp"], data["Value"])
- ax1.set_title("Time Domain")
- ax1.set_xlabel("Timestamp")
- ax1.set_ylabel("Value")
- # Remove DC offset
- data_without_dc = data["Value"] - data["Value"].mean()
- # Perform Fourier analysis
- fft_values = np.fft.fft(data_without_dc)
- frequencies = np.fft.fftfreq(len(data), d=1 / sampling_rate)
- amplitudes = np.abs(fft_values)
- # Consider only positive frequencies
- positive_frequencies = frequencies[:len(frequencies)//2]
- positive_amplitudes = amplitudes[:len(frequencies)//2]
- # Plot frequency spectrum
- ax2.plot(positive_frequencies, positive_amplitudes)
- ax2.set_title("Frequency Domain")
- ax2.set_xlabel("Frequency (Hz)")
- ax2.set_ylabel("Amplitude")
- # Initialize the plot
- init_plot()
- # Create sliders
- start_slider = ctk.CTkSlider(master=root, from_=data["Timestamp"].min(), to=data["Timestamp"].max(),
- command=lambda value: update_plot(value, end_slider.get()))
- start_slider.pack()
- end_slider = ctk.CTkSlider(master=root, from_=data["Timestamp"].min(), to=data["Timestamp"].max(),
- command=lambda value: update_plot(start_slider.get(), value))
- end_slider.pack()
- # Create a frame on the right side for displaying relevant information
- info_frame = ctk.CTkFrame(master=root)
- info_frame.pack(side=ctk.RIGHT, fill=ctk.BOTH, expand=True)
- # Labels for displaying information
- sampling_rate_label = ctk.CTkLabel(master=info_frame, text=f"Sampling Rate: {sampling_rate} Hz")
- sampling_rate_label.pack()
- max_frequency_label = ctk.CTkLabel(master=info_frame, text=f"Max Frequency: {sampling_rate / 2} Hz (Nyquist Frequency)")
- max_frequency_label.pack()
- # Button to change data file
- change_file_button = ctk.CTkButton(master=info_frame, text="Change File", command=update_data)
- change_file_button.pack()
- # Run the CustomTkinter event loop
- root.mainloop()
|