import tkinter as tk
from tkinter import Button, Label, StringVar, filedialog, messagebox
from tkinter.ttk import Combobox
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
import aviary.api as av
from aviary.utils.functions import get_path
[docs]
def plot_drag_polar(input_file=None):
"""Plot drag polar."""
if input_file is None:
input_file = filedialog.askopenfilename(filetypes=[('CSV files', '*.csv')])
if not input_file:
messagebox.showerror('Error', 'No file selected')
exit()
return
try:
input_path = get_path(input_file)
polar_data = av.read_data_file(
input_path,
aliases={
'altitude': 'altitude',
'mach_number': 'mach_number',
'alpha': 'angle_of_attack',
'CL': 'lift_coefficient',
'CD': 'total_drag_coefficient',
},
)
except Exception as e:
messagebox.showerror('Error', f'Failed to read the file: {str(e)}')
return
mach = polar_data.get_val('mach_number')
mach_values = np.unique(mach)
altitude = polar_data.get_val('altitude')
altitude_values = np.unique(altitude)
alpha_values = polar_data.get_val('alpha')
CD_values = polar_data.get_val('CD')
CL_values = polar_data.get_val('CL')
window = tk.Tk()
window.title('Drag Polar Plot')
fig, ax = plt.subplots(nrows=1)
fig.tight_layout(pad=4)
canvas = FigureCanvasTkAgg(fig, master=window)
canvas.get_tk_widget().pack(expand=True, fill='both')
toolbar = NavigationToolbar2Tk(canvas, window)
def plot_polar(ax, CD, CL, color, label=None, marker='o'):
ax.plot(CD, CL, color=color, label=label, marker='o')
def update_plot():
x_var = set_x_var.get()
y_var = set_y_var.get()
fix_variable = fix_variable_var.get()
fix_value = float(fix_value_var.get())
ax.clear()
if fix_variable == 'Mach':
indices = mach == fix_value
fixed_values = altitude_values
fixed_label = 'Altitude'
else:
index = altitude == fix_value
fixed_values = mach_values
fixed_label = 'Mach'
colors = cm.viridis(np.linspace(0, 1, len(fixed_values)))
for i, val in enumerate(fixed_values):
if fix_variable == 'Mach':
indices = (mach == fix_value) & (altitude == val)
CD = np.array(CD_values[indices])
CL = CL_values[indices]
alpha = alpha_values[indices]
else:
index = (altitude == fix_value) & (mach == val)
CD = np.array(CD_values[index])
CL = CL_values[index]
alpha = alpha_values[index]
if x_var == 'CD':
x_val = CD
elif x_var == 'CL':
x_val = CL
elif x_var == 'Alpha':
x_val = alpha
elif x_var == 'CL/CD':
x_val = np.array(CL) / np.array(CD)
if y_var == 'CD':
y_val = CD
elif y_var == 'CL':
y_val = CL
elif y_var == 'Alpha':
y_val = alpha
elif y_var == 'CL/CD':
y_val = np.array(CL) / np.array(CD)
plot_polar(ax, x_val, y_val, color=colors[i], label=f'{fixed_label} {val}')
ax.set_xlabel(f'{x_var}')
ax.set_ylabel(f'{y_var}')
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5), title=fixed_label)
ax.set_title(f'{y_var} vs {x_var} for fixed {fix_variable} = {fix_value}')
canvas.draw()
toolbar.update()
def update_fix_value_combobox(*args):
if fix_variable_var.get() == 'Mach':
fix_value_combobox['values'] = [str(value) for value in mach_values]
fix_value_var.set(str(mach_values[0]))
fix_value_combobox.current(0)
else:
fix_value_combobox['values'] = [str(value) for value in altitude_values]
fix_value_var.set(str(altitude_values[0]))
set_x_var = StringVar(value='CD')
set_x_label = Label(master=window, text='x-axis')
set_x_label.pack(side='left', padx=5, pady=5)
set_x_combobox = Combobox(
master=window, textvariable=set_x_var, values=['CD', 'CL', 'Alpha', 'CL/CD']
)
set_x_combobox.pack(side='left', padx=5, pady=5)
set_y_var = StringVar(value='CL')
set_y_label = Label(master=window, text='y-axis')
set_y_label.pack(side='left', padx=5, pady=5)
set_y_combobox = Combobox(
master=window, textvariable=set_y_var, values=['CL', 'CD', 'Alpha', 'CL/CD']
)
set_y_combobox.pack(side='left', padx=5, pady=5)
fix_variable_var = StringVar(value='Mach')
fix_value_var = StringVar(value=float(mach_values[0]))
fix_variable_label = Label(master=window, text='Fix Variable:')
fix_variable_label.pack(side='left', padx=5, pady=5)
fix_variable_combobox = Combobox(
master=window, textvariable=fix_variable_var, values=['Mach', 'Altitude']
)
fix_variable_combobox.pack(side='left', padx=5, pady=5)
fix_variable_combobox.bind('<<ComboboxSelected>>', update_fix_value_combobox)
fix_variable_combobox.current(0)
fix_value_label = Label(master=window, text='Fix Value:')
fix_value_label.pack(side='left', padx=5, pady=5)
fix_value_combobox = Combobox(master=window, textvariable=fix_value_var)
fix_value_combobox.pack(side='left', padx=5, pady=5)
update_fix_value_combobox()
plot_button = Button(master=window, text='Plot', command=update_plot)
plot_button.pack(side='right', padx=5, pady=5)
window.mainloop()
def _setup_plot_drag_polar_parser(parser):
"""
Set up the command line options for the Model Building tool.
Parameters
----------
parser : argparse.ArgumentParser
The parser instance.
parser : argparse subparser
The parser we're adding options to.
"""
pass
def _exec_plot_drag_polar(options, user_args):
"""
Run the Model Building tool.
Parameters
----------
options : argparse.Namespace
Command line options.
user_args : list of str
Args to be passed to the user script.
"""
plot_drag_polar()
if __name__ == '__main__':
plot_drag_polar()