Skip to content

Instantly share code, notes, and snippets.

@futureshocked
Last active June 2, 2024 02:47
Show Gist options
  • Save futureshocked/05799e1e25128bb5b49a157d885dd669 to your computer and use it in GitHub Desktop.
Save futureshocked/05799e1e25128bb5b49a157d885dd669 to your computer and use it in GitHub Desktop.
This program plots heading, speed and altitude and creates an animated gif.
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