Python, and you kind of want to take the long way around.
Get it up and running in its own virtual environment. On Linux and Windows this'll just be a directory its in, and once you've activated that install via a terminal command everything stays self contained. It has a package manager called "pip" that will handle package and dependency management. Use pip to install spyder, pandas, matplotlib, numpy, scipy, and openpyxl. If you install anaconda this is what it's doing under the hood, but there are licensing hiccups with using their package repos.
Anyway, however you get up and going, numpy is fast numerical storage, scipy is a lot of scientific algorithms, pandas is a data analysis library that rides on top of numpy, and openpyxl is an interface to excel files from python. Pandas will get you one line CSV file reads and writes and more complex manipulation of Excel spreadsheets. Openpyxl gets you cell by cell manipulation of a spreadsheet. Spyder is a development environment.
It can do much, much more.
I asked an LLM for a small python example with pandas and matplotlib. Load it into spyder and run it and see what happens (tip, go into the settings/preferences, IPython Console, Plotting, and change the Graphics Backend to "Qt" to get the plots in their own window).
Python Example
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def generate_damped_signal():
# 1. Setup Parameters
fs = 50 # 50Hz Sampling frequency
t_max = 6.0 # Run for 6 seconds to clearly visualize it hitting 0 at 5s
freq = 2.0 # Oscillation frequency in Hz
# 2. Generate Independent Time Axis
# 50 samples per second from 0 to t_max
time = np.arange(0, t_max, 1/fs)
# 3. Generate Dependent Damped Signal Axis
# Using an exponential decay constant of 1.0 ensures that at t=5 seconds,
# e^(-5) drops down to ~0.006, effectively decaying the signal to zero.
amplitude = np.exp(-time) * np.cos(2 * np.pi * freq * time)
# 4. Create Pandas DataFrame
df = pd.DataFrame({
'Time_Seconds': time,
'Signal_Amplitude': amplitude
})
# 5. Export DataFrame to CSV File
csv_filename = "damped_signal.csv"
df.to_csv(csv_filename, index=False)
print(f"Successfully generated DataFrame and saved to '{csv_filename}'")
# 6. Plot the Data Using Matplotlib
plt.figure(figsize=(10, 5))
plt.plot(df['Time_Seconds'], df['Signal_Amplitude'], label='Damped Signal', color='cyan', linewidth=2)
# Visual Anchors for the 5-second decay mark
plt.axvline(x=5.0, color='red', linestyle='--', alpha=0.7, label='5-Second Decay Target')
plt.axhline(y=0.0, color='gray', linestyle='-', alpha=0.5)
# Labeling and Grid Configuration
plt.title('Damped Signal Decay Over Time (50Hz Sampling Rate)')
plt.xlabel('Time (Independent Axis - Seconds)')
plt.ylabel('Signal (Dependent Axis - Amplitude)')
plt.grid(True, linestyle=':', alpha=0.6)
plt.legend()
# Display the Plot Window
plt.show()
if __name__ == "__main__":
generate_damped_signal()