Source code for RCAIDE.Library.Plots.Performance.plot_V_n_diagram

# RCAIDE/Library/Plots/Performance/plot_V_n_diagram.py
# 
# 
# Created: Feb 2026, M. Clarke

# ----------------------------------------------------------------------------------------------------------------------
#  IMPORT
# ----------------------------------------------------------------------------------------------------------------------

# RCAIDE imports 
from RCAIDE.Framework.Core import Units   
from RCAIDE.Library.Plots.Common import set_axes, plot_style     

# Pacakge imports  
from matplotlib import pyplot as plt  

# ----------------------------------------------------------------------------------------------------------------------
#  PLOTS
# ----------------------------------------------------------------------------------------------------------------------   
[docs] def plot_V_n_diagram(V_n_data, vehicle = None, save_figure = False, show_legend = True, save_filename = "V_n_Diagram", file_type =".png", generate_report = False, width = 8, height = 6): """ Plot graph, save the final figure, and create results output file Source: Inputs: V_n_data. airspeeds.positive [kts] airspeeds.negative [kts] Vc [kts] Vd [kts] Vs1.positive [kts] negative [kts] Va.positive [kts] negative [kts] load_factors.positive [Unitless] negative [Unitless] gust_load_factors.positive [Unitless] negative [Unitless] weight [lb] altitude [ft] vehicle._base.tag [Unitless] Uref_rough [ft/s] Uref_cruise [ft/s] Uref_dive [ft/s] Outputs: Properties Used: N/A Description: """ # Unpack load_factors_pos = V_n_data.load_factors.positive load_factors_neg = V_n_data.load_factors.negative airspeeds_pos = V_n_data.airspeeds.positive airspeeds_neg = V_n_data.airspeeds.negative Vc = V_n_data.Vc Vd = V_n_data.Vd Vs1_pos = V_n_data.Vs1.positive Vs1_neg = V_n_data.Vs1.negative Va_pos = V_n_data.Va.positive Va_neg = V_n_data.Va.negative gust_load_factors_pos = V_n_data.gust_load_factors.positive gust_load_factors_neg = V_n_data.gust_load_factors.negative weight = V_n_data.weight altitude = V_n_data.altitude Uref_rough = V_n_data.gust_data.airspeeds.rough_gust Uref_cruise = V_n_data.gust_data.airspeeds.cruise_gust Uref_dive = V_n_data.gust_data.airspeeds.dive_gust category_tag = V_n_data.category_tag #----------------------------- # Plotting the V-n diagram #----------------------------- # get plotting style ps = plot_style() parameters = {'axes.labelsize': ps.axis_font_size, 'xtick.labelsize': ps.axis_font_size, 'ytick.labelsize': ps.axis_font_size, 'axes.titlesize': ps.title_font_size} plt.rcParams.update(parameters) fig = plt.figure(save_filename) fig.set_size_inches(width,height) ax = fig.add_subplot(1,1,1) ax.fill(airspeeds_pos, load_factors_pos, c='b', alpha=0.3) ax.fill(airspeeds_neg, load_factors_neg, c='b', alpha=0.3) ax.plot(airspeeds_pos, load_factors_pos, c='b') ax.plot(airspeeds_neg, load_factors_neg, c='b') # Plotting gust lines ax.plot([0, Vc,1.05*Vd],[1,gust_load_factors_pos[2],gust_load_factors_pos[len(gust_load_factors_pos)-3]],'--', c='r', label = ('Gust ' + str(round(Uref_cruise)) + 'fps')) ax.plot([0, Vd,1.05*Vd],[1,gust_load_factors_pos[3],gust_load_factors_pos[len(gust_load_factors_pos)-2]],'--', c='g', label = ('Gust ' + str(round(Uref_dive)) + 'fps')) ax.plot([0, Vc,1.05*Vd],[1,gust_load_factors_neg[2],gust_load_factors_neg[len(gust_load_factors_neg)-3]],'--', c='r') ax.plot([0, Vd,1.05*Vd],[1,gust_load_factors_neg[3],gust_load_factors_neg[len(gust_load_factors_neg)-2]],'--', c='g') if category_tag == 'commuter': ax.plot([0, 1.05*Vd],[1,gust_load_factors_pos[len(gust_load_factors_pos)-1]],'--', c='m', label = ('Gust ' + str(round(Uref_rough)) + 'fps')) ax.plot([0, 1.05*Vd],[1,gust_load_factors_neg[len(gust_load_factors_neg)-1]],'--', c='m') # Formating the plot ax.set_xlabel('Airspeed, KEAS') ax.set_ylabel('Load Factor') ax.legend() ax.grid() #--------------------------------- # Creating results output file #--------------------------------- if generate_report: fres = open("V_n_diagram_results_" + V_n_data.tag +".dat","w") fres.write('V-n diagram summary\n') fres.write('-------------------\n') fres.write('Aircraft: ' + V_n_data.tag + '\n') fres.write('category: ' + V_n_data.category + '\n') fres.write('FAR certification: Part ' + V_n_data.FAR_part_number + '\n') fres.write('Weight = ' + str(round(weight)) + ' lb\n') fres.write('Altitude = ' + str(round(altitude)) + ' ft\n') fres.write('---------------------------------------------------------------\n\n') fres.write('Airspeeds: \n') fres.write(' Positive stall speed (Vs1) = ' + str(round(Vs1_pos,1)) + ' KEAS\n') fres.write(' Negative stall speed (Vs1) = ' + str(round(Vs1_neg,1)) + ' KEAS\n') fres.write(' Positive maneuver speed (Va) = ' + str(round(Va_pos,1)) + ' KEAS\n') fres.write(' Negative maneuver speed (Va) = ' + str(round(Va_neg,1)) + ' KEAS\n') fres.write(' Cruise speed (Vc) = ' + str(round(Vc,1)) + ' KEAS\n') fres.write(' Dive speed (Vd) = ' + str(round(Vd,1)) + ' KEAS\n') fres.write('Load factors: \n') fres.write(' Positive limit load factor (n+) = ' + str(round(max(load_factors_pos),2)) + '\n') fres.write(' Negative limit load factor (n-) = ' + str(round(min(load_factors_neg),2)) + '\n') fres.write(' Positive load factor at Vd = ' + str(round(V_n_data.limit_loads.dive.positive,2)) + '\n') fres.write(' Negative load factor at Vd = ' + str(round(V_n_data.limit_loads.dive.negative,2)) + '\n') # Adjusting the sub-plots for legend fig.tight_layout() if save_figure: fig.savefig(save_filename + file_type) return fig