Last active
June 2, 2024 02:47
-
-
Save futureshocked/05799e1e25128bb5b49a157d885dd669 to your computer and use it in GitHub Desktop.
This program plots heading, speed and altitude and creates an animated gif.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas as pd | |
import numpy as np | |
import matplotlib.pyplot as plt | |
import matplotlib.animation as animation | |
import sys | |
import os | |
# This is version 4 of the program | |
def create_compass_animation(file_path): | |
# Load the flight data | |
flight_data = pd.read_csv(file_path) | |
# Number of frames | |
num_frames = len(flight_data) | |
print(f'The movie contains {num_frames} frames.') | |
# Convert time from milliseconds to seconds | |
# flight_data['time (s)'] = flight_data['time (ms)'] / 1000 | |
# Set up the figure and axes | |
fig, ((ax1), (ax2), (ax3), (ax4)) = plt.subplots(4, 1, figsize=(10, 20)) | |
# Setting up the first plot (Compass) | |
ax1.set_xlim(-1.5, 1.5) | |
ax1.set_ylim(-1.5, 1.5) | |
ax1.set_aspect('equal') | |
ax1.set_title('Compass Heading') | |
# Create a circle for the compass | |
circle = plt.Circle((0, 0), 1, color='black', fill=False) | |
ax1.add_artist(circle) | |
# Add heading markings | |
for angle in range(0, 360, 30): | |
x = np.cos(np.deg2rad(angle)) | |
y = np.sin(np.deg2rad(angle)) | |
ax1.text(x * 1.1, y * 1.1, f'{angle}°', ha='center', va='center') | |
# Create the compass needle | |
needle, = ax1.plot([], [], 'r-', lw=2) | |
# Setting up the second plot (Heading over time) | |
ax2.set_xlim(0, flight_data['time (s)'].iloc[-1]) | |
ax2.set_ylim(flight_data['angle (deg)'].min() - 10, flight_data['angle (deg)'].max() + 10) | |
ax2.set_xlabel('Time (s)') | |
ax2.set_ylabel('Heading (deg)') | |
ax2.set_title('Heading over Time') | |
heading_line, = ax2.plot([], [], 'b-') | |
# Adding segment labels | |
segment_labels = { | |
'Upwind': 60, | |
'Crosswind': 150, | |
'Downwind': 240, | |
'Base': 330 | |
} | |
for label, heading in segment_labels.items(): | |
ax2.axhline(heading, color='gray', linestyle='--', linewidth=0.5) | |
ax2.text(0, heading + 5, label, color='gray', fontsize=12, ha='left') | |
# Setting up the third plot (Speed over time) | |
ax3.set_xlim(0, flight_data['time (s)'].iloc[-1]) | |
ax3.set_ylim(flight_data['speed (kn)'].min() - 10, flight_data['speed (kn)'].max() + 10) | |
ax3.set_xlabel('Time (s)') | |
ax3.set_ylabel('Speed (kn)') | |
ax3.set_title('Speed over Time') | |
speed_line, = ax3.plot([], [], 'g-') | |
# Setting up the fourth plot (Altitude over time) | |
ax4.set_xlim(0, flight_data['time (s)'].iloc[-1]) | |
ax4.set_ylim(flight_data['alt (m)'].min() - 10, flight_data['alt (m)'].max() + 10) | |
ax4.set_xlabel('Time (s)') | |
ax4.set_ylabel('Altitude (m)') | |
ax4.set_title('Altitude over Time') | |
altitude_line, = ax4.plot([], [], 'm-') | |
# Initialize the plot data | |
heading_time = [] | |
heading_angle = [] | |
speed_time = [] | |
speed_data = [] | |
altitude_time = [] | |
altitude_data = [] | |
# Function to initialize the plot | |
def init(): | |
needle.set_data([], []) | |
heading_line.set_data([], []) | |
speed_line.set_data([], []) | |
altitude_line.set_data([], []) | |
return needle, heading_line, speed_line, altitude_line, | |
# Function to update the plots | |
def update(frame): | |
angle = np.deg2rad(flight_data['angle (deg)'].iloc[frame]) | |
x = [0, np.cos(angle)] | |
y = [0, np.sin(angle)] | |
needle.set_data(x, y) | |
heading_time.append(flight_data['time (s)'].iloc[frame]) | |
heading_angle.append(flight_data['angle (deg)'].iloc[frame]) | |
heading_line.set_data(heading_time, heading_angle) | |
speed_time.append(flight_data['time (s)'].iloc[frame]) | |
speed_data.append(flight_data['speed (kn)'].iloc[frame]) | |
speed_line.set_data(speed_time, speed_data) | |
altitude_time.append(flight_data['time (s)'].iloc[frame]) | |
altitude_data.append(flight_data['alt (m)'].iloc[frame]) | |
altitude_line.set_data(altitude_time, altitude_data) | |
return needle, heading_line, speed_line, altitude_line, | |
# Create the animation | |
ani = animation.FuncAnimation(fig, update, frames=num_frames, init_func=init, blit=True, interval=50) | |
# Define the output file name in the same directory as the input file | |
base_name = os.path.splitext(file_path)[0] | |
animation_path = f'{base_name}_heading_animation.gif' | |
# Save the animation as GIF | |
ani.save(animation_path, writer='pillow') | |
print(f'Animation saved as {animation_path}') | |
if __name__ == "__main__": | |
if len(sys.argv) != 2: | |
print("Usage: python script_name.py <file_path>") | |
else: | |
file_path = sys.argv[1] | |
create_compass_animation(file_path) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment