def __init__(self, config, orbit_type): self.orbit = [] self.config = config self.orbitType = orbit_type self.massParameter = 0.0121505810173 self.figSize = (20, 20) self.titleSize = 20 self.suptitleSize = 30 orbit_ids = [] for orbit_id in list(self.config[self.orbitType].keys()): ls = orbit_id.split('_') if orbit_type == 'near_vertical': orbit_ids.append(int(ls[2])) if orbit_type == 'halo': orbit_ids.append(int(ls[1])) orbit_ids = [ self.orbitType + '_' + str(idx) for idx in sorted(orbit_ids) ] for orbit_id in orbit_ids: self.orbit.append( load_orbit('../data/raw/' + orbit_id + '_final_orbit.txt')) self.lagrangePoints = load_lagrange_points_location() self.bodies = load_bodies_location() sns.set_style("whitegrid") pass
def show_2d_subplots(self): df = pd.DataFrame.from_dict(self.config[orbit_type]).T # colors = sns.color_palette("Blues", n_colors=6) for orbit_id, row in df.iterrows(): f, axarr = plt.subplots(2, 1, figsize=self.figSize) orbit = load_orbit('../data/raw/' + orbit_id + '_final_orbit.txt') label = '$x_0$ = ' + str(np.round(row['x'], 3)) \ + '\n$y_0$ = ' + str(np.round(row['y'], 3)) \ + '\n$z_0$ = ' + str(np.round(row['z'], 3)) \ + '\n$\dot{x}_0$ = ' + str(np.round(row['x_dot'], 3)) \ + '\n$\dot{y}_0$ = ' + str(np.round(row['y_dot'], 3)) \ + '\n$\dot{z}_0$ = ' + str(np.round(row['z_dot'], 3)) axarr[0].plot(orbit['y'].values, orbit['z'].values, color='darkblue', label=label) circ = plt.Circle((0, 0), radius=1, edgecolor='k', facecolor='None', linestyle=':') axarr[1].add_patch(circ) for j in range(1, 7): x = row['l_' + str(j) + '_re'] y = row['l_' + str(j) + '_im'] axarr[1].scatter(x, y, color='darkblue', label='$\lambda_' + str(j) + '$ = (' + str(np.round(x, 2)) + ', ' + str(np.round(y, 2)) + ')') axarr[0].set_title('T = ' + str(np.round(row['T'], 2)) + ', C = ' + str(np.round(row['C'], 2))) for k in range(2): # Shrink current axis box = axarr[k].get_position() axarr[k].set_position( [box.x0, box.y0, box.width * 0.75, box.height]) # Put a legend to the right of the current axis axarr[k].legend(loc='center left', bbox_to_anchor=(1, 0.5)) axarr[1].set_xlim([-10, 10]) axarr[1].set_ylim([-5, 5]) plt.suptitle(orbit_id, size=self.suptitleSize) plt.savefig('../data/figures/eigenvalues_' + orbit_id + '_2d.png') plt.close() pass
def __init__(self, orbit_type, lagrange_point_nr, orbit_id, c_level): self.orbitType = orbit_type self.orbitId = orbit_id self.cLevel = c_level self.orbitTypeForTitle = orbit_type.capitalize() if (self.orbitTypeForTitle == 'Horizontal') or (self.orbitTypeForTitle == 'Vertical'): self.orbitTypeForTitle += ' Lyapunov' self.lagrangePointNr = lagrange_point_nr EARTH_GRAVITATIONAL_PARAMETER = 3.986004418E14 SUN_GRAVITATIONAL_PARAMETER = 1.32712440018e20 MOON_GRAVITATIONAL_PARAMETER = SUN_GRAVITATIONAL_PARAMETER / (328900.56 * (1.0 + 81.30059)) self.massParameter = MOON_GRAVITATIONAL_PARAMETER / (MOON_GRAVITATIONAL_PARAMETER + EARTH_GRAVITATIONAL_PARAMETER) self.eigenvectorDf_S = pd.read_table('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_S_plus_eigenvector.txt', delim_whitespace=True, header=None).filter(list(range(6))) self.eigenvectorDf_U = pd.read_table('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_U_plus_eigenvector.txt', delim_whitespace=True, header=None).filter(list(range(6))) self.eigenvectorLocationDf_S = pd.read_table('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_S_plus_eigenvector_location.txt', delim_whitespace=True, header=None).filter(list(range(6))) self.eigenvectorLocationDf_U = pd.read_table('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_U_plus_eigenvector_location.txt', delim_whitespace=True, header=None).filter(list(range(6))) self.W_S_plus = load_manifold_refactored('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_S_plus.txt') self.W_S_min = load_manifold_refactored('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_S_min.txt') self.W_U_plus = load_manifold_refactored('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_U_plus.txt') self.W_U_min = load_manifold_refactored('../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_U_min.txt') self.orbitDf = load_orbit('../../data/raw/orbits/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '.txt') self.numberOfOrbitsPerManifold = len(set(self.W_S_plus.index.get_level_values(0))) self.figSize = (7 * (1 + np.sqrt(5)) / 2, 7) blues = sns.color_palette('Blues', 100) greens = sns.color_palette('BuGn', 100) self.colorPaletteStable = sns.dark_palette('green', n_colors=self.numberOfOrbitsPerManifold) self.colorPaletteUnstable = sns.dark_palette('red', n_colors=self.numberOfOrbitsPerManifold) n_colors = 3 n_colors_l = 6 self.plottingColors = {'lambda1': sns.color_palette("viridis", n_colors_l)[0], 'lambda2': sns.color_palette("viridis", n_colors_l)[2], 'lambda3': sns.color_palette("viridis", n_colors_l)[4], 'lambda4': sns.color_palette("viridis", n_colors_l)[5], 'lambda5': sns.color_palette("viridis", n_colors_l)[3], 'lambda6': sns.color_palette("viridis", n_colors_l)[1], 'singleLine': sns.color_palette("viridis", n_colors)[0], 'doubleLine': [sns.color_palette("viridis", n_colors)[n_colors - 1], sns.color_palette("viridis", n_colors)[0]], 'tripleLine': [sns.color_palette("viridis", n_colors)[n_colors - 1], sns.color_palette("viridis", n_colors)[int((n_colors - 1) / 2)], sns.color_palette("viridis", n_colors)[0]], 'W_S_plus': self.colorPaletteStable[int(0.9*self.numberOfOrbitsPerManifold)], 'W_S_min': self.colorPaletteStable[int(0.4*self.numberOfOrbitsPerManifold)], 'W_U_plus': self.colorPaletteUnstable[int(0.9*self.numberOfOrbitsPerManifold)], 'W_U_min': self.colorPaletteUnstable[int(0.4*self.numberOfOrbitsPerManifold)], 'limit': 'black', 'orbit': 'navy'} self.suptitleSize = 20 pass
def update_lines(self, i): if i % 10 == 0: print(i) for j, line in enumerate(self.lines): if i <= self.orbitIdBifurcations[0]: jacobi_energy = self.jacobiEnergyHorizontalLyapunov[i] self.jacobiEnergyText.set_text('Horizontal Lyapunov family \n $C \\approx$ {:.4f}'.format(round(jacobi_energy, 4))) orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_horizontal_' + str(i) + '.txt') elif self.orbitIdBifurcations[0] < i <= self.orbitIdBifurcations[0] + self.numberOfHaloExtensionOrbits: index_for_halo = self.numberOfHaloExtensionOrbits - (i - self.orbitIdBifurcations[0]) jacobi_energy = self.jacobiEnergyHaloN[(i - self.orbitIdBifurcations[0] - 1)] self.jacobiEnergyText.set_text('Southern halo family \n $C \\approx$ {:.4f}'.format(round(jacobi_energy, 4))) orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_halo_n_' + str(index_for_halo) + '.txt') pass else: index_for_halo = i - self.orbitIdBifurcations[0] - self.numberOfHaloExtensionOrbits + 1 jacobi_energy = self.jacobiEnergyHalo[index_for_halo] self.jacobiEnergyText.set_text('Southern halo family \n $C \\approx$ {:.4f}'.format(round(jacobi_energy, 4))) orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_halo_' + str(index_for_halo) + '.txt') pass if i == self.orbitIdBifurcations[0]: plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color='navy', linewidth=2) x = orbit_df['x'].tolist() y = orbit_df['y'].tolist() z = orbit_df['z'].tolist() line.set_data(x, y) line.set_3d_properties(z) pass if i % 100 == 0 and i != 0: plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color='gray', linewidth=1) return self.lines
'../data/raw/vertical_L2_initial_conditions.txt') initial_conditions_halo_L1 = load_initial_conditions_incl_M( '../data/raw/halo_L1_initial_conditions.txt') initial_conditions_halo_L2 = load_initial_conditions_incl_M( '../data/raw/halo_L2_initial_conditions.txt') horizontal_L1 = [] horizontal_L2 = [] vertical_L1 = [] vertical_L2 = [] halo_L1 = [] halo_L2 = [] for orbit_id in list(range(len(initial_conditions_horizontal_L1))): horizontal_L1.append( load_orbit('../data/raw/horizontal_L1_' + str(orbit_id) + '.txt')) for orbit_id in list(range(len(initial_conditions_horizontal_L2))): horizontal_L2.append( load_orbit('../data/raw/horizontal_L2_' + str(orbit_id) + '.txt')) for orbit_id in list(range(len(initial_conditions_vertical_L1))): vertical_L1.append( load_orbit('../data/raw/vertical_L1_' + str(orbit_id) + '.txt')) for orbit_id in list(range(len(initial_conditions_vertical_L2))): vertical_L2.append( load_orbit('../data/raw/vertical_L2_' + str(orbit_id) + '.txt')) for orbit_id in list(range(len(initial_conditions_halo_L1))): halo_L1.append(load_orbit('../data/raw/halo_L1_' + str(orbit_id) + '.txt')) for orbit_id in list(range(len(initial_conditions_halo_L2))): halo_L2.append(load_orbit('../data/raw/halo_L2_' + str(orbit_id) + '.txt')) # Create plot
def plot(self): colors = sns.color_palette("Blues", n_colors=6) # Plot: 3d overview fig = plt.figure(figsize=(7 * (1 + np.sqrt(5)) / 2, 7)) ax = fig.gca(projection='3d') # Plot both primaries u = np.linspace(0, 2 * np.pi, 100) v = np.linspace(0, np.pi, 100) bodies_df = load_bodies_location() for body in bodies_df: x = bodies_df[body]['r'] * np.outer( np.cos(u), np.sin(v)) + bodies_df[body]['x'] y = bodies_df[body]['r'] * np.outer(np.sin(u), np.sin(v)) z = bodies_df[body]['r'] * np.outer(np.ones(np.size(u)), np.cos(v)) ax.plot_surface(x, y, z, color='black') # Plot Lagrange points 1 and 2 lagrange_points_df = load_lagrange_points_location() lagrange_point_nrs = ['L1', 'L2'] for lagrange_point_nr in lagrange_point_nrs: ax.scatter3D(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['y'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x', s=50) # ax.annotate('Moon', xy=(-0.002,0.004), # xytext=(-0.002, 0.04), fontsize=20, ha = 'center', va = 'top', # arrowprops=dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0'), # ) # ax.annotate('$L_1$', xy=(-0.023, 0.012), # xytext=(-0.023, 0.04), fontsize=20, ha='center', va='top', # arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0'), # ) # ax.annotate('$L_2$', xy=(0.023, -0.004), # xytext=(0.023, 0.04), fontsize=20, ha='center', va='top', # arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0'), # ) # params = {'legend.fontsize': 16} # plt.rcParams.update(params) C = 3.1 # x_range = np.arange(0.7, 1.3, 0.001) # y_range = np.arange(-0.3, 0.3, 0.001) x_range = np.arange(0.8, 1.2, 0.001) y_range = np.arange(-0.2, 0.2, 0.001) X, Y = np.meshgrid(x_range, y_range) Z = cr3bp_velocity(X, Y, C) if Z.min() < 0: plt.contourf(X, Y, Z, 0, colors='black', alpha=0.05, zorder=1000) linewidth = 2 df = load_orbit('../../data/raw_equal_energy/horizontal_L1_577.txt') ax.plot(df['x'], df['y'], df['z'], color=sns.color_palette("viridis", 3)[0], alpha=0.75, linestyle='-', label='Horizontal Lyapunov', linewidth=linewidth) df = load_orbit('../../data/raw_equal_energy/halo_L1_799.txt') ax.plot(df['x'], df['y'], df['z'], color=sns.color_palette("viridis", 3)[2], alpha=0.75, linestyle='-', label='Halo', linewidth=linewidth) df = load_orbit('../../data/raw_equal_energy/vertical_L1_1163.txt') ax.plot(df['x'], df['y'], df['z'], color=sns.color_palette("viridis", 3)[1], alpha=0.75, linestyle='-', label='Vertical Lyapunov', linewidth=linewidth) ax.legend(frameon=True, loc='lower right') df = load_orbit('../../data/raw_equal_energy/horizontal_L2_760.txt') ax.plot(df['x'], df['y'], df['z'], color=sns.color_palette("viridis", 3)[0], alpha=0.75, linestyle='-', linewidth=linewidth) df = load_orbit('../../data/raw_equal_energy/vertical_L2_1299.txt') ax.plot(df['x'], df['y'], df['z'], color=sns.color_palette("viridis", 3)[1], alpha=0.75, linestyle='-', linewidth=linewidth) df = load_orbit('../../data/raw_equal_energy/halo_L2_651.txt') ax.plot(df['x'], df['y'], df['z'], color=sns.color_palette("viridis", 3)[2], alpha=0.75, linestyle='-', linewidth=linewidth) ax.set_xlabel('x [-]') ax.set_ylabel('y [-]') ax.set_zlabel('z [-]') ax.grid(True, which='both', ls=':') # ax.view_init(25, -60) ax.view_init(20, -60) # ax.set_xlim([0.7, 1.3]) # ax.set_ylim([-0.3, 0.3]) # ax.set_zlim([-0.3, 0.3]) ax.set_xlim([0.8, 1.2]) ax.set_ylim([-0.2, 0.2]) ax.set_zlim([-0.2, 0.2]) plt.tight_layout() # plt.show() # fig.savefig('../../../data/figures/family_of_equal_energy.png') if self.lowDPI: fig.savefig('../../data/figures/new_family_of_equal_energy.png', transparent=True, dpi=self.dpi) else: fig.savefig('../../data/figures/new_family_of_equal_energy.pdf', transparent=True) # tikz_save('../../../data/figures/family_of_equal_energy.tex') plt.close() pass
import numpy as np import pandas as pd import json import matplotlib # matplotlib.use('Agg') # Must be before importing matplotlib.pyplot or pylab! import matplotlib.pyplot as plt import matplotlib as mpl from mpl_toolkits.mplot3d import Axes3D from mpl_toolkits.axes_grid.inset_locator import inset_axes # import seaborn as sns from load_data import load_orbit, load_bodies_location, load_lagrange_points_location, cr3bp_velocity mpl.rcParams['axes.linewidth'] = 5 orbit = load_orbit('../../data/verification/ver_halo_1_final_orbit.txt') orbit['x'] = (orbit['x'] - 1) * 384400e-4 orbit['y'] = orbit['y'] * 384400e-4 eigenvectors_S = pd.read_table( '../../data/verification/ver_halo_1_W_S_plus.txt', delim_whitespace=True, header=None).filter(list(range(6))) eigenvectors_U = pd.read_table( '../../data/verification/ver_halo_1_W_U_plus.txt', delim_whitespace=True, header=None).filter(list(range(6))) eigenvectors_S.columns = ['x', 'y', 'z', 'xdot', 'ydot', 'zdot'] eigenvectors_U.columns = ['x', 'y', 'z', 'xdot', 'ydot', 'zdot'] eigenvectors_indices = [np.floor(i * len(orbit) / 20) for i in range(20)]
def animate(self): fig = plt.figure() self.ax = fig.add_subplot(111, projection='3d') self.horizontalLyapunov = [ load_orbit('../../../data/raw/orbits/L' + str(1) + '_horizontal_' + str(self.orbitIds['horizontal'][1][self.cLevel]) + '_100.txt'), load_orbit('../../../data/raw/orbits/L' + str(2) + '_horizontal_' + str(self.orbitIds['horizontal'][2][self.cLevel]) + '_100.txt') ] self.verticalLyapunov = [ load_orbit('../../../data/raw/orbits/L' + str(1) + '_vertical_' + str(self.orbitIds['vertical'][1][self.cLevel]) + '_100.txt'), load_orbit('../../../data/raw/orbits/L' + str(2) + '_vertical_' + str(self.orbitIds['vertical'][2][self.cLevel]) + '_100.txt') ] self.halo = [ load_orbit('../../../data/raw/orbits/L' + str(1) + '_halo_' + str(self.orbitIds['halo'][1][self.cLevel]) + '_100.txt'), load_orbit('../../../data/raw/orbits/L' + str(2) + '_halo_' + str(self.orbitIds['halo'][2][self.cLevel]) + '_100.txt') ] self.lines = [ plt.plot([], [], color=self.orbitColor, alpha=self.orbitAlpha, marker='o', markevery=[-1])[0] for idx in range(6) ] # Text object to display absolute normalized time of trajectories within the manifolds self.timeText = self.ax.text2D(0.05, 0.05, s='$\|t\| \\approx 0$', transform=self.ax.transAxes, size=self.timeTextSize) # Plot zero velocity surface x_range = np.arange(self.xLim[0], self.xLim[1], 0.001) y_range = np.arange(self.yLim[0], self.yLim[1], 0.001) x_mesh, y_mesh = np.meshgrid(x_range, y_range) z_mesh = cr3bp_velocity(x_mesh, y_mesh, c_level) if z_mesh.min() < 0: plt.contour(x_mesh, y_mesh, z_mesh, [z_mesh.min(), 0], colors='black', alpha=0.3) # Plot both orbits for k in range(2): plt.plot(self.horizontalLyapunov[k]['x'], self.horizontalLyapunov[k]['y'], self.horizontalLyapunov[k]['z'], color=self.orbitColor, alpha=self.orbitAlpha, linewidth=self.orbitLinewidth, linestyle=':') plt.plot(self.verticalLyapunov[k]['x'], self.verticalLyapunov[k]['y'], self.verticalLyapunov[k]['z'], color=self.orbitColor, alpha=self.orbitAlpha, linewidth=self.orbitLinewidth, linestyle=':') plt.plot(self.halo[k]['x'], self.halo[k]['y'], self.halo[k]['z'], color=self.orbitColor, alpha=self.orbitAlpha, linewidth=self.orbitLinewidth, linestyle=':') # Plot both primaries u = np.linspace(0, 2 * np.pi, 100) v = np.linspace(0, np.pi, 100) bodies_df = load_bodies_location() for body in bodies_df: x = bodies_df[body]['r'] * np.outer( np.cos(u), np.sin(v)) + bodies_df[body]['x'] y = bodies_df[body]['r'] * np.outer(np.sin(u), np.sin(v)) z = bodies_df[body]['r'] * np.outer(np.ones(np.size(u)), np.cos(v)) self.ax.plot_surface(x, y, z, color='black') # Plot Lagrange points 1 and 2 lagrange_points_df = load_lagrange_points_location() lagrange_point_nrs = ['L1', 'L2'] for lagrange_point_nr in lagrange_point_nrs: self.ax.scatter3D(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['y'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x', s=self.lagrangePointMarkerSize) title = 'Types of periodic libration point motion - Rotating spatial overview at C = ' + str( c_level) self.ax.set_xlim3d(self.xLim) self.ax.set_ylim3d(self.yLim) self.ax.set_zlim3d(self.zLim) self.ax.set_xlabel('x [-]') self.ax.set_ylabel('y [-]') self.ax.set_zlabel('z [-]') self.ax.grid(True, which='both', ls=':') fig.tight_layout() fig.subplots_adjust(top=0.9) plt.suptitle(title, size=self.suptitleSize) # Fix overlap between labels and ticks self.ax.xaxis._axinfo['label']['space_factor'] = 2.0 self.ax.yaxis._axinfo['label']['space_factor'] = 2.0 self.ax.zaxis._axinfo['label']['space_factor'] = 2.0 self.initialElevation = self.ax.elev self.initialAzimuth = self.ax.azim # Determine the maximum value of t t_max = 0 for lagrange_point_idx in [0, 1]: t_max = max( t_max, self.horizontalLyapunov[lagrange_point_idx].tail(1) ['time'].values[0]) t_max = max( t_max, self.verticalLyapunov[lagrange_point_idx].tail(1) ['time'].values[0]) t_max = max( t_max, self.halo[lagrange_point_idx].tail(1)['time'].values[0]) print('Maximum value for t = ' + str(t_max) + ', animation t: = ') # Introduce a new time-vector for linearly spaced time throughout the animation self.t = np.linspace(0, t_max, np.round(t_max / 0.005) + 1) animation_function = animation.FuncAnimation( fig, self.update_lines, init_func=self.initiate_lines, frames=len(self.t), interval=1, blit=True) empty_writer_object = animation.writers['ffmpeg'] animation_writer = empty_writer_object( fps=30, metadata=dict(artist='Koen Langemeijer')) file_name = '../../../data/animations/orbits/spatial_orbits_rotating_' + str( c_level) + '.mp4' animation_function.save(file_name, writer=animation_writer)
orbit_type = 'horizontal' lagrange_point_nr = 1 # Load data initial_conditions_file_path = '../data/raw/' + orbit_type + '_L' + str( lagrange_point_nr) + '_initial_conditions.txt' initial_conditions_df = load_initial_conditions(initial_conditions_file_path) orbit_ids = list(range(len(initial_conditions_df))) orbit = [] for orbit_id in orbit_ids: orbit.append( load_orbit('../data/raw/' + orbit_type + '_L' + str(lagrange_point_nr) + '_' + str(orbit_id) + '.txt')) label_orbit = '$x_0$ = ' + str(np.round(initial_conditions_df.iloc[0]['x'], 3)) \ + '\n$y_0$ = ' + str(np.round(initial_conditions_df.iloc[0]['y'], 3)) \ + '\n$z_0$ = ' + str(np.round(initial_conditions_df.iloc[0]['z'], 3)) \ + '\n$\dot{x}_0$ = ' + str(np.round(initial_conditions_df.iloc[0]['xdot'], 3)) \ + '\n$\dot{y}_0$ = ' + str(np.round(initial_conditions_df.iloc[0]['ydot'], 3)) \ + '\n$\dot{z}_0$ = ' + str(np.round(initial_conditions_df.iloc[0]['zdot'], 3)) # Create plot fig = plt.figure(figsize=(20, 20)) plt.rcParams[ 'animation.ffmpeg_path'] = 'ffmpeg-git-20170607-64bit-static/ffmpeg' gs = GridSpec(2, 2) ax1 = plt.subplot(gs[0, :-1], projection='3d') ax2 = plt.subplot(gs[0, -1])
def plot_family(self): c_normalized = [(value - min(self.C)) / (max(self.C) - min(self.C)) for value in self.C] colors = matplotlib.colors.ListedColormap( sns.color_palette("viridis_r"))(c_normalized) # colors = matplotlib.colors.ListedColormap(sns.dark_palette("blue", reverse=True))(c_normalized) sm = plt.cm.ScalarMappable(cmap=matplotlib.colors.ListedColormap( sns.color_palette("viridis", len(self.C))), norm=plt.Normalize(vmin=min(self.C), vmax=max(self.C))) # sm = plt.cm.ScalarMappable(cmap=sns.dark_palette("blue", as_cmap=True, reverse=True), norm=plt.Normalize(vmin=min(self.C), vmax=max(self.C))) # clean the array of the scalar mappable sm._A = [] # Plot 1: 3d overview fig1 = plt.figure(figsize=self.figSize) ax1 = fig1.gca() # Plot 2: subplots if self.orbitType == 'horizontal': fig2 = plt.figure(figsize=(self.figSize[0], self.figSize[1] / 2)) ax2 = fig2.add_subplot(1, 2, 1, projection='3d') ax5 = fig2.add_subplot(1, 2, 2) else: fig2 = plt.figure(figsize=self.figSize) ax2 = fig2.add_subplot(2, 2, 1, projection='3d') ax3 = fig2.add_subplot(2, 2, 4) ax4 = fig2.add_subplot(2, 2, 3) ax5 = fig2.add_subplot(2, 2, 2) lagrange_points_df = load_lagrange_points_location() lagrange_point_nrs = ['L1', 'L2'] # Lagrange points and bodies for lagrange_point_nr in lagrange_point_nrs: ax1.scatter(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['y'], color='black', marker='x') ax2.scatter(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['y'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x') ax5.scatter(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['y'], color='black', marker='x') if self.orbitType != 'horizontal': ax3.scatter(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x') ax4.scatter(lagrange_points_df[lagrange_point_nr]['y'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x') bodies_df = load_bodies_location() u = np.linspace(0, 2 * np.pi, 100) v = np.linspace(0, np.pi, 100) x = bodies_df['Moon']['r'] * np.outer( np.cos(u), np.sin(v)) + bodies_df['Moon']['x'] y = bodies_df['Moon']['r'] * np.outer(np.sin(u), np.sin(v)) z = bodies_df['Moon']['r'] * np.outer(np.ones(np.size(u)), np.cos(v)) ax1.contourf(x, y, z, colors='black') ax2.plot_surface(x, y, z, color='black') ax5.contourf(x, y, z, colors='black') if self.orbitType != 'horizontal': ax3.contourf(x, z, y, colors='black') ax4.contourf(y, z, x, colors='black') # Determine color for plot # colorOrderOfLinearInstability = ['whitesmoke', 'silver', 'dimgrey'] plot_alpha = 1 line_width = 0.5 # Plot every 100th member, including the ultimate member of the family spacing_factor = 100 orbitIdsPlot = list(range(0, len(self.C) - 1, spacing_factor)) if orbitIdsPlot[-1] != len(self.C) - 1: orbitIdsPlot.append(len(self.C) - 1) # Plot orbits for i in orbitIdsPlot: # plot_color = colorOrderOfLinearInstability[self.orderOfLinearInstability[i]] nan_correction = sum( [1 for nan in self.indexNanEntries if nan < i]) plot_color = colors[self.plotColorIndexBasedOnC[i - nan_correction]] df = load_orbit('../../data/raw/orbits/extended/L' + str(self.lagrangePointNr) + '_' + self.orbitType + '_' + str(i) + '.txt') ax1.plot(df['x'], df['y'], color=plot_color, alpha=plot_alpha, linewidth=line_width) ax2.plot(df['x'], df['y'], df['z'], color=plot_color, alpha=plot_alpha, linewidth=line_width) ax5.plot(df['x'], df['y'], color=plot_color, alpha=plot_alpha, linewidth=line_width) if self.orbitType != 'horizontal': ax3.plot(df['x'], df['z'], color=plot_color, alpha=plot_alpha, linewidth=line_width) ax4.plot(df['y'], df['z'], color=plot_color, alpha=plot_alpha, linewidth=line_width) # # Plot the bifurcations # for i in self.orbitIdBifurcations: # # plot_color = 'b' # nan_correction = sum([1 for nan in self.indexNanEntries if nan < i]) # plot_color = colors[self.plotColorIndexBasedOnC[i - nan_correction]] # df = load_orbit('../../data/raw/orbits/extended/L' + str(self.lagrangePointNr) + '_' + self.orbitType + '_' + str(i) + '.txt') # ax1.plot(df['x'], df['y'], color=plot_color, linewidth=3) # ax2.plot(df['x'], df['y'], df['z'], color=plot_color, linewidth=3) # ax5.plot(df['x'], df['y'], color=plot_color, linewidth=3) # if self.orbitType != 'horizontal': # ax3.plot(df['x'], df['z'], color=plot_color, linewidth=3) # ax4.plot(df['y'], df['z'], color=plot_color, linewidth=3) ax1.set_xlabel('x [-]') ax1.set_ylabel('y [-]') ax1.grid(True, which='both', ls=':') ax2.set_xlabel('x [-]') ax2.set_ylabel('y [-]') ax2.set_zlabel('z [-]') ax2.set_zlim([-1.2, 1.2]) ax2.grid(True, which='both', ls=':') ax2.view_init(30, -120) if self.orbitType != 'horizontal': ax3.set_xlabel('x [-]') ax3.set_ylabel('z [-]') ax3.set_ylim([-1.2, 1.2]) ax3.grid(True, which='both', ls=':') ax4.set_xlabel('y [-]') ax4.set_ylabel('z [-]') ax4.set_ylim([-1.2, 1.2]) ax4.grid(True, which='both', ls=':') ax5.set_xlabel('x [-]') ax5.set_ylabel('y [-]') ax5.grid(True, which='both', ls=':') fig2.tight_layout() if self.orbitType == 'horizontal': fig2.subplots_adjust(top=0.8) else: fig2.subplots_adjust(top=0.9) if self.orbitType != 'horizontal': cax, kw = matplotlib.colorbar.make_axes([ax2, ax3, ax4, ax5]) else: cax, kw = matplotlib.colorbar.make_axes([ax2, ax5]) cbar = plt.colorbar(sm, cax=cax, label='C [-]', **kw) plt.suptitle('$L_' + str(self.lagrangePointNr) + '$ ' + self.orbitTypeForTitle + ' - Orthographic projection', size=self.suptitleSize) fig1.suptitle('$L_' + str(self.lagrangePointNr) + '$ ' + self.orbitTypeForTitle + ': family', size=self.suptitleSize) fig2.savefig('../../data/figures/orbits/extended/L' + str(self.lagrangePointNr) + '_' + self.orbitType + '_family_subplots.pdf', transparent=True) plt.close(fig2) plt.close() pass
def __init__(self, orbit_type, lagrange_point_nr): self.C = [] self.T = [] self.x = [] self.X = [] self.delta_r = [] self.delta_v = [] self.delta_x = [] self.delta_y = [] self.delta_z = [] self.delta_x_dot = [] self.delta_y_dot = [] self.delta_z_dot = [] self.numberOfIterations = [] self.C_half_period = [] self.T_half_period = [] self.X_half_period = [] self.eigenvalues = [] self.D = [] self.orderOfLinearInstability = [] self.orbitIdBifurcations = [] self.lambda1 = [] self.lambda2 = [] self.lambda3 = [] self.lambda4 = [] self.lambda5 = [] self.lambda6 = [] self.v1 = [] self.v2 = [] self.v3 = [] self.lagrangePointNr = lagrange_point_nr print('=======================') print(str(orbit_type) + ' in L' + str(lagrange_point_nr)) print('=======================') self.orbitType = orbit_type self.orbitTypeForTitle = orbit_type.capitalize() if self.orbitTypeForTitle == 'Horizontal' or self.orbitTypeForTitle == 'Vertical': self.orbitTypeForTitle += ' Lyapunov' initial_conditions_file_path = '../../data/raw/orbits/extended/L' + str(lagrange_point_nr) + '_' \ + orbit_type + '_initial_conditions.txt' initial_conditions_incl_m_df = load_initial_conditions_incl_M( initial_conditions_file_path) differential_correction_file_path = '../../data/raw/orbits/extended/L' + str(lagrange_point_nr) + '_' \ + orbit_type + '_differential_correction.txt' differential_correction_df = load_differential_corrections( differential_correction_file_path) # Fix for extended v-l self.indexNanEntries = pd.isnull(initial_conditions_incl_m_df).any( 1).nonzero()[0] print(self.indexNanEntries) initial_conditions_incl_m_df.dropna(axis=0, how='any', inplace=True) differential_correction_df.drop( differential_correction_df.index[self.indexNanEntries], inplace=True) for row in differential_correction_df.iterrows(): self.numberOfIterations.append(row[1][0]) self.C_half_period.append(row[1][1]) self.T_half_period.append(row[1][2]) self.X_half_period.append(np.array(row[1][3:9])) self.maxEigenvalueDeviation = 1.0e-3 # Changed from 1e-3 for row in initial_conditions_incl_m_df.iterrows(): self.C.append(row[1][0]) self.T.append(row[1][1]) self.x.append(row[1][2]) self.X.append(np.array(row[1][2:8])) # self.X.append(np.array(row[1][3:9])) M = np.matrix([ list(row[1][8:14]), list(row[1][14:20]), list(row[1][20:26]), list(row[1][26:32]), list(row[1][32:38]), list(row[1][38:44]) ]) eigenvalue = np.linalg.eigvals(M) print(str(row[0]) + ' at x-loc: ' + str(row[1][2])) sorting_indices = [-1, -1, -1, -1, -1, -1] idx_real_one = [] # Find indices of the first pair of real eigenvalue equal to one for idx, l in enumerate(eigenvalue): if abs(l.imag) < self.maxEigenvalueDeviation: if abs(l.real - 1.0) < self.maxEigenvalueDeviation: if sorting_indices[2] == -1: sorting_indices[2] = idx idx_real_one.append(idx) elif sorting_indices[3] == -1: sorting_indices[3] = idx idx_real_one.append(idx) # Find indices of the pair of largest/smallest real eigenvalue (corresponding to the unstable/stable subspace) for idx, l in enumerate(eigenvalue): if idx == (sorting_indices[2] or sorting_indices[3]): continue if abs(l.imag) < self.maxEigenvalueDeviation: if abs(l.real) == max(abs(eigenvalue.real)): sorting_indices[0] = idx elif abs(abs(l.real) - 1.0 / max(abs(eigenvalue.real)) ) < self.maxEigenvalueDeviation: sorting_indices[5] = idx missing_indices = sorted( list(set(list(range(-1, 6))) - set(sorting_indices))) if eigenvalue.imag[missing_indices[0]] > eigenvalue.imag[ missing_indices[1]]: sorting_indices[1] = missing_indices[0] sorting_indices[4] = missing_indices[1] else: sorting_indices[1] = missing_indices[1] sorting_indices[4] = missing_indices[0] # reset sorting index for regime halo in l1 if orbit_type == 'halo' and lagrange_point_nr == 1 and row[ 0] >= 1972 and row[0] <= 2316: sorting_indices = [ -1, -1, idx_real_one[0], idx_real_one[1], -1, -1 ] # # TODO check that all indices are unique and no - if len(sorting_indices) > len(set(sorting_indices)): print('\nWARNING: SORTING INDEX IS NOT UNIQUE FOR ' + self.orbitType + ' AT L' + str(self.lagrangePointNr)) print(eigenvalue) if len(idx_real_one) != 2: idx_real_one = [] # Find indices of the first pair of real eigenvalue equal to one for idx, l in enumerate(eigenvalue): if abs(l.imag) < 2 * self.maxEigenvalueDeviation: if abs(l.real - 1.0) < 2 * self.maxEigenvalueDeviation: if sorting_indices[2] == -1: sorting_indices[2] = idx idx_real_one.append(idx) elif sorting_indices[3] == -1: sorting_indices[3] = idx idx_real_one.append(idx) if len(idx_real_one) == 2: sorting_indices = [-1, -1, -1, -1, -1, -1] sorting_indices[2] = idx_real_one[0] sorting_indices[3] = idx_real_one[1] print('minimum angle = ' + str( min( abs( np.angle(eigenvalue[list( set(range(6)) - set(idx_real_one))], deg=True))))) print('maximum angle = ' + str( max( abs( np.angle(eigenvalue[list( set(range(6)) - set(idx_real_one))], deg=True))))) # Assume two times real one and two conjugate pairs for idx, l in enumerate(eigenvalue): print(idx) print(abs(np.angle(l, deg=True))) # min(abs(np.angle(eigenvalue[list(set(range(6)) - set(idx_real_one))], deg=True))) # if abs(np.angle(l, deg=True))%180 == min(abs(np.angle(eigenvalue[list(set(range(6)) - set(idx_real_one))], deg=True)) %180): if l.real == eigenvalue[list( set(range(6)) - set(idx_real_one))].real.max(): if l.imag > 0: sorting_indices[0] = idx elif l.imag < 0: sorting_indices[5] = idx # if abs(np.angle(l, deg=True))%180 == max(abs(np.angle(eigenvalue[list(set(range(6)) - set(idx_real_one))], deg=True)) %180): if l.real == eigenvalue[list( set(range(6)) - set(idx_real_one))].real.min(): if l.imag > 0: sorting_indices[1] = idx elif l.imag < 0: sorting_indices[4] = idx print(sorting_indices) if len(sorting_indices) > len(set(sorting_indices)): print('\nWARNING: SORTING INDEX IS STILL NOT UNIQUE') # Sorting eigenvalues from largest to smallest norm, excluding real one # Sorting based on previous phase if len(idx_real_one) == 2: sorting_indices = [-1, -1, -1, -1, -1, -1] sorting_indices[2] = idx_real_one[0] sorting_indices[3] = idx_real_one[1] # Assume two times real one and two conjugate pairs for idx, l in enumerate( eigenvalue[list(set(range(6)) - set(idx_real_one))]): print(idx) if abs(l.real - self.lambda1[-1].real) == min( abs(eigenvalue.real - self.lambda1[-1].real) ) and abs(l.imag - self.lambda1[-1].imag) == min( abs(eigenvalue.imag - self.lambda1[-1].imag)): sorting_indices[0] = idx if abs(l.real - self.lambda2[-1].real) == min( abs(eigenvalue.real - self.lambda2[-1].real) ) and abs(l.imag - self.lambda2[-1].imag) == min( abs(eigenvalue.imag - self.lambda2[-1].imag)): sorting_indices[1] = idx if abs(l.real - self.lambda5[-1].real) == min( abs(eigenvalue.real - self.lambda5[-1].real) ) and abs(l.imag - self.lambda5[-1].imag) == min( abs(eigenvalue.imag - self.lambda5[-1].imag)): sorting_indices[4] = idx if abs(l.real - self.lambda6[-1].real) == min( abs(eigenvalue.real - self.lambda6[-1].real) ) and abs(l.imag - self.lambda6[-1].imag) == min( abs(eigenvalue.imag - self.lambda6[-1].imag)): sorting_indices[5] = idx print(sorting_indices) pass if (sorting_indices[1] and sorting_indices[4]) == -1: # Fill two missing values two_missing_indices = list( set(list(range(-1, 6))) - set(sorting_indices)) if abs(eigenvalue[two_missing_indices[0]].real) > abs( eigenvalue[two_missing_indices[1]].real): sorting_indices[1] = two_missing_indices[0] sorting_indices[4] = two_missing_indices[1] else: sorting_indices[1] = two_missing_indices[1] sorting_indices[4] = two_missing_indices[0] print(sorting_indices) if (sorting_indices[0] and sorting_indices[5]) == -1: # Fill two missing values two_missing_indices = list( set(list(range(-1, 6))) - set(sorting_indices)) print(eigenvalue) print(sorting_indices) print(two_missing_indices) # TODO quick fix for extended v-l # if len(two_missing_indices)==1: # print('odd that only one index remains') # if sorting_indices[0] == -1: # sorting_indices[0] = two_missing_indices[0] # else: # sorting_indices[5] = two_missing_indices[0] # sorting_indices = abs(eigenvalue).argsort()[::-1] if abs(eigenvalue[two_missing_indices[0]].real) > abs( eigenvalue[two_missing_indices[1]].real): sorting_indices[0] = two_missing_indices[0] sorting_indices[5] = two_missing_indices[1] else: sorting_indices[0] = two_missing_indices[1] sorting_indices[5] = two_missing_indices[0] print(sorting_indices) if len(sorting_indices) > len(set(sorting_indices)): print('\nWARNING: SORTING INDEX IS STILL STILL NOT UNIQUE') # Sorting eigenvalues from largest to smallest norm, excluding real one sorting_indices = abs(eigenvalue).argsort()[::-1] print(eigenvalue[sorting_indices]) self.eigenvalues.append(eigenvalue[sorting_indices]) self.lambda1.append(eigenvalue[sorting_indices[0]]) self.lambda2.append(eigenvalue[sorting_indices[1]]) self.lambda3.append(eigenvalue[sorting_indices[2]]) self.lambda4.append(eigenvalue[sorting_indices[3]]) self.lambda5.append(eigenvalue[sorting_indices[4]]) self.lambda6.append(eigenvalue[sorting_indices[5]]) # Determine order of linear instability reduction = 0 for i in range(6): if (abs(eigenvalue[i]) - 1.0) < 1e-2: reduction += 1 if len(self.orderOfLinearInstability) > 0: # Check for a bifurcation, when the order of linear instability changes if (6 - reduction) != self.orderOfLinearInstability[-1]: self.orbitIdBifurcations.append(row[0]) self.orderOfLinearInstability.append(6 - reduction) self.v1.append( abs(eigenvalue[sorting_indices[0]] + eigenvalue[sorting_indices[5]]) / 2) self.v2.append( abs(eigenvalue[sorting_indices[1]] + eigenvalue[sorting_indices[4]]) / 2) self.v3.append( abs(eigenvalue[sorting_indices[2]] + eigenvalue[sorting_indices[3]]) / 2) self.D.append(np.linalg.det(M)) print('Index for bifurcations: ') print(self.orbitIdBifurcations) # Determine heatmap for level of C self.numberOfPlotColorIndices = len(self.C) self.plotColorIndexBasedOnC = [] for jacobi_energy in self.C: self.plotColorIndexBasedOnC.append( int( np.round((jacobi_energy - min(self.C)) / (max(self.C) - min(self.C)) * (self.numberOfPlotColorIndices - 1)))) for i in range(0, len(initial_conditions_incl_m_df)): df = load_orbit('../../data/raw/orbits/extended/L' + str(self.lagrangePointNr) + '_' + self.orbitType + '_' + str(i) + '.txt') self.delta_r.append( np.sqrt((df.head(1)['x'].values - df.tail(1)['x'].values)**2 + (df.head(1)['y'].values - df.tail(1)['y'].values)**2 + (df.head(1)['z'].values - df.tail(1)['z'].values)**2)) self.delta_v.append( np.sqrt((df.head(1)['xdot'].values - df.tail(1)['xdot'].values)**2 + (df.head(1)['ydot'].values - df.tail(1)['ydot'].values)**2 + (df.head(1)['zdot'].values - df.tail(1)['zdot'].values)**2)) self.delta_x.append( abs(df.head(1)['x'].values - df.tail(1)['x'].values)) self.delta_y.append( abs(df.head(1)['y'].values - df.tail(1)['y'].values)) self.delta_z.append( abs(df.head(1)['z'].values - df.tail(1)['z'].values)) self.delta_x_dot.append( abs(df.head(1)['xdot'].values - df.tail(1)['xdot'].values)) self.delta_y_dot.append( abs(df.head(1)['ydot'].values - df.tail(1)['ydot'].values)) self.delta_z_dot.append( abs(df.head(1)['zdot'].values - df.tail(1)['zdot'].values)) # self.figSize = (20, 20) self.figSize = (7 * (1 + np.sqrt(5)) / 2, 7) n_colors = 3 n_colors_l = 6 self.plottingColors = { 'lambda1': sns.color_palette("viridis", n_colors_l)[0], 'lambda2': sns.color_palette("viridis", n_colors_l)[2], 'lambda3': sns.color_palette("viridis", n_colors_l)[4], 'lambda4': sns.color_palette("viridis", n_colors_l)[5], 'lambda5': sns.color_palette("viridis", n_colors_l)[3], 'lambda6': sns.color_palette("viridis", n_colors_l)[1], 'singleLine': sns.color_palette("viridis", n_colors)[0], 'doubleLine': [ sns.color_palette("viridis", n_colors)[n_colors - 1], sns.color_palette("viridis", n_colors)[0] ], 'tripleLine': [ sns.color_palette("viridis", n_colors)[n_colors - 1], sns.color_palette("viridis", n_colors)[int( (n_colors - 1) / 2)], sns.color_palette("viridis", n_colors)[0] ], 'limit': 'black' } self.suptitleSize = 20 self.xlim = [min(self.x), max(self.x)] pass
source_directory = '../src/verification/' source_name = 'halo_verification_l1' plot_suptitle = 'Halo verification L1 (Howell)' with open(source_directory + source_name + '.json') as data_file: config = json.load(data_file) df = pd.DataFrame.from_dict(config[orbit_type]).T f, axarr = plt.subplots(6, 2, figsize=(10, 15)) colors = sns.color_palette("Blues", n_colors=6) row_nr = 0 for idx, row in df.iterrows(): orbit = load_orbit('../src/verification/' + idx + '_l1.txt') label = '$x_0$ = ' + str(row['x']) + '\n$y_0$ = ' + str(row['y']) + '\n$z_0$ = ' + str(row['z']) \ + '\n$\dot{x}_0$ = ' + str(row['x_dot']) + '\n$\dot{y}_0$ = ' + str(row['y_dot']) + '\n$\dot{z}_0$ = ' \ + str(row['z_dot']) axarr[row_nr, 0].plot(orbit['x'], orbit['y'], color='darkblue', label=label) circ = plt.Circle((0, 0), radius=1, edgecolor='k', facecolor='None', linestyle=':') axarr[row_nr, 1].add_patch(circ)
def animate(self): self.W_S_plus = [ load_manifold_refactored( '../../../data/raw/manifolds/refined_for_c/L' + str(1) + '_' + self.orbitType + '_' + str(self.orbitIds[0]) + '_W_S_plus.txt'), load_manifold_refactored( '../../../data/raw/manifolds/refined_for_c/L' + str(2) + '_' + self.orbitType + '_' + str(self.orbitIds[1]) + '_W_S_plus.txt') ] self.W_S_min = [ load_manifold_refactored( '../../../data/raw/manifolds/refined_for_c/L' + str(1) + '_' + self.orbitType + '_' + str(self.orbitIds[0]) + '_W_S_min.txt'), load_manifold_refactored( '../../../data/raw/manifolds/refined_for_c/L' + str(2) + '_' + self.orbitType + '_' + str(self.orbitIds[1]) + '_W_S_min.txt') ] self.W_U_plus = [ load_manifold_refactored( '../../../data/raw/manifolds/refined_for_c/L' + str(1) + '_' + self.orbitType + '_' + str(self.orbitIds[0]) + '_W_U_plus.txt'), load_manifold_refactored( '../../../data/raw/manifolds/refined_for_c/L' + str(2) + '_' + self.orbitType + '_' + str(self.orbitIds[1]) + '_W_U_plus.txt') ] self.W_U_min = [ load_manifold_refactored( '../../../data/raw/manifolds/refined_for_c/L' + str(1) + '_' + self.orbitType + '_' + str(self.orbitIds[0]) + '_W_U_min.txt'), load_manifold_refactored( '../../../data/raw/manifolds/refined_for_c/L' + str(2) + '_' + self.orbitType + '_' + str(self.orbitIds[1]) + '_W_U_min.txt') ] self.numberOfOrbitsPerManifold = len( set(self.W_S_plus[0].index.get_level_values(0))) color_palette_green = sns.dark_palette( 'green', n_colors=self.numberOfOrbitsPerManifold) color_palette_red = sns.dark_palette( 'red', n_colors=self.numberOfOrbitsPerManifold) self.lines = [ self.ax.plot([], [], color=color_palette_red[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold) ] self.lines.extend([ self.ax.plot([], [], color=color_palette_green[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold) ]) self.lines.extend([ self.ax.plot([], [], color=color_palette_red[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold) ]) self.lines.extend([ self.ax.plot([], [], color=color_palette_green[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold) ]) self.lines.extend([ self.ax.plot([], [], color=color_palette_red[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold) ]) self.lines.extend([ self.ax.plot([], [], color=color_palette_green[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold) ]) self.lines.extend([ self.ax.plot([], [], color=color_palette_green[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold) ]) self.lines.extend([ self.ax.plot([], [], color=color_palette_red[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold) ]) # Text object to display absolute normalized time of trajectories within the manifolds self.timeText = self.ax.text2D(0.05, 0.05, s='$\|t\| \\approx 0$', transform=self.ax.transAxes, size=self.timeTextSize) # Plot zero velocity surface x_range = np.arange(self.xLim[0], self.xLim[1], 0.001) y_range = np.arange(self.yLim[0], self.yLim[1], 0.001) x_mesh, y_mesh = np.meshgrid(x_range, y_range) z_mesh = cr3bp_velocity(x_mesh, y_mesh, self.cLevel) if z_mesh.min() < 0: self.ax.contour(x_mesh, y_mesh, z_mesh, [z_mesh.min(), 0], colors='black', alpha=0.3) # Plot both orbits for k in range(2): orbit_df = load_orbit('../../../data/raw/orbits/refined_for_c/L' + str(k + 1) + '_' + self.orbitType + '_' + str(self.orbitIds[k]) + '.txt') self.ax.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color=self.orbitColor, alpha=self.orbitAlpha, linewidth=self.orbitLinewidth) # Plot both primaries u = np.linspace(0, 2 * np.pi, 100) v = np.linspace(0, np.pi, 100) bodies_df = load_bodies_location() for body in bodies_df: x = bodies_df[body]['r'] * np.outer( np.cos(u), np.sin(v)) + bodies_df[body]['x'] y = bodies_df[body]['r'] * np.outer(np.sin(u), np.sin(v)) z = bodies_df[body]['r'] * np.outer(np.ones(np.size(u)), np.cos(v)) self.ax.plot_surface(x, y, z, color='black') # Plot Lagrange points 1 and 2 lagrange_points_df = load_lagrange_points_location() lagrange_point_nrs = ['L1', 'L2'] for lagrange_point_nr in lagrange_point_nrs: self.ax.scatter3D(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['y'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x', s=self.lagrangePointMarkerSize) title = self.orbitTypeForTitle + ' $\{ \mathcal{W}^{S \pm}, \mathcal{W}^{U \pm} \}$ - Orthographic projection (C = ' + str( c_level) + ')' # self.ax.set_xlim3d(self.xLim) # self.ax.set_ylim3d(self.yLim) # self.ax.set_zlim3d(self.zLim) self.ax.set_xlim(self.xLim) self.ax.set_ylim(self.yLim) self.ax.set_zlim(self.zLim) self.ax.axis('off') # fig.tight_layout() self.fig.subplots_adjust(top=0.9) self.fig.suptitle(title, size=self.suptitleSize) self.initialElevation = self.ax.elev self.initialAzimuth = self.ax.azim # Determine the maximum value of t t_max = 0 for lagrange_point_idx in [0, 1]: for index in range(self.numberOfOrbitsPerManifold): t_max = max( t_max, abs(self.W_S_plus[lagrange_point_idx].xs(index).head( 1).index.values[0])) t_max = max( t_max, abs(self.W_S_min[lagrange_point_idx].xs(index).head( 1).index.values[0])) t_max = max( t_max, abs(self.W_U_plus[lagrange_point_idx].xs(index).tail( 1).index.values[0])) t_max = max( t_max, abs(self.W_U_min[lagrange_point_idx].xs(index).tail( 1).index.values[0])) print('Maximum value for t = ' + str(t_max) + ', animation t: = ') # Introduce a new time-vector for linearly spaced time throughout the animation self.t = np.linspace(0, t_max, np.round(t_max / 0.01) + 1) self.animation_function = animation.FuncAnimation( self.fig, self.update_lines, init_func=self.initiate_lines, frames=len(self.t), interval=1, blit=True) self.empty_writer_object = animation.writers['ffmpeg'] self.animation_writer = self.empty_writer_object( fps=30, metadata=dict(artist='Koen Langemeijer')) self.file_name = '../../../data/animations/manifolds/spatial_manifolds_rotating_no_axes_' + self.orbitType + '_' + str( self.cLevel) + '.mp4' self.animation_function.save(self.file_name, writer=self.animation_writer)
def update_lines(self, i): if i % 10 == 0: print(i) index_for_vertical = 0 for j, line in enumerate(self.lines): if i <= self.orbitIdBifurcationsFromHorizontalLyapunov[1]: jacobi_energy = self.jacobiEnergyHorizontalLyapunov[i] self.jacobiEnergyText.set_text( 'Horizontal Lyapunov family \n $C \\approx$ {:.4f}'.format( round(jacobi_energy, 4))) orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_horizontal_' + str(i) + '.txt') elif self.orbitIdBifurcationsFromHorizontalLyapunov[ 1] < i <= self.orbitIdBifurcationsFromHorizontalLyapunov[ 1] + self.numberOfAxialOrbits: index_for_axial = i - self.orbitIdBifurcationsFromHorizontalLyapunov[ 1] - 1 jacobi_energy = self.jacobiEnergyAxial[index_for_axial] self.jacobiEnergyText.set_text( 'Axial family \n $C \\approx$ {:.4f}'.format( round(jacobi_energy, 4))) orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_axial_' + str(index_for_axial) + '.txt') else: index_for_vertical = self.verticalLyapunovIndices[ i - self.orbitIdBifurcationsFromHorizontalLyapunov[1] - self.numberOfAxialOrbits - 1] jacobi_energy = self.jacobiEnergyVerticalLyapunov[ index_for_vertical] self.jacobiEnergyText.set_text( 'Vertical Lyapunov family \n $C \\approx$ {:.4f}'.format( round(jacobi_energy, 4))) orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_vertical_' + str(index_for_vertical) + '.txt') if i in self.orbitIdBifurcationsFromHorizontalLyapunov and i <= self.orbitIdBifurcationsFromHorizontalLyapunov[ 1]: plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color='navy', linewidth=2) if index_for_vertical == self.orbitIdBifurcationsFromVerticalLyapunov[ 0]: plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color='navy', linewidth=2) x = orbit_df['x'].tolist() y = orbit_df['y'].tolist() z = orbit_df['z'].tolist() line.set_data(x, y) line.set_3d_properties(z) pass if i % 100 == 0 and i != 0: plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color='gray', linewidth=1) return self.lines
def update_lines(self, i): if i % 10 == 0: print(i) index_for_vertical = 0 for j, line in enumerate(self.lines): if i <= self.orbitIdBifurcationsFromHorizontalLyapunov[1]: jacobi_energy = self.jacobiEnergyHorizontalLyapunov[i] self.jacobiEnergyText.set_text( 'Horizontal Lyapunov family \n $C \\approx$ {:.4f}'.format( round(jacobi_energy, 4))) orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_horizontal_' + str(i) + '.txt') elif self.orbitIdBifurcationsFromHorizontalLyapunov[ 1] < i <= self.orbitIdBifurcationsFromHorizontalLyapunov[ 1] + self.numberOfAxialOrbits: index_for_axial = i - self.orbitIdBifurcationsFromHorizontalLyapunov[ 1] - 1 jacobi_energy = self.jacobiEnergyAxial[index_for_axial] self.jacobiEnergyText.set_text( 'Axial family \n $C \\approx$ {:.4f}'.format( round(jacobi_energy, 4))) orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_axial_' + str(index_for_axial) + '.txt') line.set_color(self.orbitColors['halo']) else: index_for_vertical = self.verticalLyapunovIndices[ i - self.orbitIdBifurcationsFromHorizontalLyapunov[1] - self.numberOfAxialOrbits - 1] jacobi_energy = self.jacobiEnergyVerticalLyapunov[ index_for_vertical] self.jacobiEnergyText.set_text( 'Vertical Lyapunov family \n $C \\approx$ {:.4f}'.format( round(jacobi_energy, 4))) orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_vertical_' + str(index_for_vertical) + '.txt') line.set_color(self.orbitColors['vertical']) if i in self.orbitIdBifurcationsFromHorizontalLyapunov and i <= self.orbitIdBifurcationsFromHorizontalLyapunov[ 1]: self.ax.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color=self.orbitColors['horizontal'], linewidth=self.bifurcationLinewidth) if index_for_vertical == self.orbitIdBifurcationsFromVerticalLyapunov[ 0]: self.ax.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color=self.orbitColors['halo'], linewidth=self.bifurcationLinewidth) x = orbit_df['x'].tolist() y = orbit_df['y'].tolist() z = orbit_df['z'].tolist() line.set_data(x, y) line.set_3d_properties(z) pass if self.includeSurfaceHill: z_mesh = cr3bp_velocity(self.x_mesh, self.y_mesh, jacobi_energy) if self.setContourLastTime: for coll in self.contour.collections: self.ax.collections.remove(coll) if z_mesh.min() < 0: self.contour = self.ax.contour( self.x_mesh, self.y_mesh, z_mesh, list(np.linspace(z_mesh.min(), 0, 10)), cmap='gist_gray_r', alpha=0.5) self.setContourLastTime = True else: self.setContourLastTime = False if i % 100 == 0 and i != 0: if i <= self.orbitIdBifurcationsFromHorizontalLyapunov[1]: plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color=self.orbitColors['horizontal'], linewidth=self.orbitLinewidth) elif self.orbitIdBifurcationsFromHorizontalLyapunov[ 1] < i <= self.orbitIdBifurcationsFromHorizontalLyapunov[ 1] + self.numberOfAxialOrbits: plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color=self.orbitColors['halo'], linewidth=self.orbitLinewidth) else: plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color=self.orbitColors['vertical'], linewidth=self.orbitLinewidth) return self.lines
def animate(self): print( '\nProducing a HorizontalLyapunovBifurcationToAxialAnimation at L' + str(self.librationPointNr) + '\n') fig = plt.figure() ax = fig.add_subplot(111, projection='3d') self.lines = [ plt.plot([], [], color=self.orbitColor, alpha=self.orbitAlpha)[0] ] # Text object to display absolute normalized time of trajectories within the manifolds self.jacobiEnergyText = ax.text2D( 0.05, 0.05, s='Horizontal Lyapunov family \n $C \\approx$ {:.4f}'.format( round(self.jacobiEnergyHorizontalLyapunov[0], 4)), transform=ax.transAxes, size=self.timeTextSize) # Plot the first orbit orbit_df = load_orbit('../../../data/raw/orbits/L' + str(self.librationPointNr) + '_horizontal_' + str(0) + '.txt') plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color='orange', alpha=self.orbitAlpha, linewidth=self.orbitLinewidth) # Plot the Moon u = np.linspace(0, 2 * np.pi, 100) v = np.linspace(0, np.pi, 100) bodies_df = load_bodies_location() x = bodies_df['Moon']['r'] * np.outer( np.cos(u), np.sin(v)) + bodies_df['Moon']['x'] y = bodies_df['Moon']['r'] * np.outer(np.sin(u), np.sin(v)) z = bodies_df['Moon']['r'] * np.outer(np.ones(np.size(u)), np.cos(v)) ax.plot_surface(x, y, z, color='black') # Plot Lagrange points 1 and 2 lagrange_points_df = load_lagrange_points_location() lagrange_point_nrs = ['L1', 'L2'] for lagrange_point_nr in lagrange_point_nrs: ax.scatter3D(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['y'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x', s=self.lagrangePointMarkerSize) title = 'Bifurcation from horizontal Lyapunov to axial and vertical Lyapunov families at $L_' + str( self.librationPointNr) + '$' ax.set_xlim3d(self.xLim) ax.set_ylim3d(self.yLim) ax.set_zlim3d(self.zLim) ax.set_xlabel('x [-]') ax.set_ylabel('y [-]') ax.set_zlabel('z [-]') plt.show() ax.grid(True, which='both', ls=':') fig.tight_layout() fig.subplots_adjust(top=0.9) plt.suptitle(title, size=self.suptitleSize) # Fix overlap between labels and ticks ax.xaxis._axinfo['label']['space_factor'] = 2.0 ax.yaxis._axinfo['label']['space_factor'] = 2.0 ax.zaxis._axinfo['label']['space_factor'] = 2.0 # ax.elev = 10 # ax.azim = -80 # Determine number of frames number_of_frames = int( self.orbitIdBifurcationsFromHorizontalLyapunov[1] + 1 + self.numberOfAxialOrbits + len(self.verticalLyapunovIndices)) print('Number of frames equals ' + str(number_of_frames)) animation_function = animation.FuncAnimation( fig, self.update_lines, init_func=self.initiate_lines, frames=number_of_frames, interval=1, blit=True) empty_writer_object = animation.writers['ffmpeg'] animation_writer = empty_writer_object( fps=30, metadata=dict(artist='Koen Langemeijer')) file_name = '../../../data/animations/bifurcations/L' + str( self.librationPointNr ) + '_horizontal_lyapunov_bifurcation_to_axial_family.mp4' animation_function.save(file_name, writer=animation_writer)
fig = plt.figure(figsize=(20, 20)) ax = fig.add_subplot(111, projection='3d') plt.rcParams[ 'animation.ffmpeg_path'] = 'ffmpeg-git-20170607-64bit-static/ffmpeg' ax.set_xlim3d([1.1, 1.2]) ax.set_xlabel('x') ax.set_ylim3d([-0.05, 0.05]) ax.set_ylabel('y') ax.set_zlim3d([-0.05, 0.05]) ax.set_zlabel('z') time_text = ax.text(1, 1, 1, s='', transform=ax.transAxes, size=22) orbit = load_orbit('../data/raw/' + orbit_name + '_final_orbit.txt') manifold_S_plus = load_manifold('../data/raw/' + orbit_name + '_W_S_plus.txt') manifold_S_min = load_manifold('../data/raw/' + orbit_name + '_W_S_min.txt') manifold_U_plus = load_manifold('../data/raw/' + orbit_name + '_W_U_plus.txt') manifold_U_min = load_manifold('../data/raw/' + orbit_name + '_W_U_min.txt') plt.plot(orbit['x'], orbit['y'], orbit['z'], color='blue') C = float(config[orbit_type][orbit_name]['C']) x_range = np.arange(0.5, 1.5, 0.001) y_range = np.arange(-0.5, 0.5, 0.001) X, Y = np.meshgrid(x_range, y_range)
def __init__(self, orbit_type, lagrange_point_nr, orbit_id_per_c): print('=======================') print(str(orbit_type) + ' in L' + str(lagrange_point_nr)) print('=======================') self.orbitType = orbit_type self.orbitIdPerC = orbit_id_per_c self.orbitTypeForTitle = orbit_type.capitalize() if (self.orbitTypeForTitle == 'Horizontal') or (self.orbitTypeForTitle == 'Vertical'): self.orbitTypeForTitle += ' Lyapunov' self.lagrangePointNr = lagrange_point_nr EARTH_GRAVITATIONAL_PARAMETER = 3.986004418E14 SUN_GRAVITATIONAL_PARAMETER = 1.32712440018e20 MOON_GRAVITATIONAL_PARAMETER = SUN_GRAVITATIONAL_PARAMETER / ( 328900.56 * (1.0 + 81.30059)) self.massParameter = MOON_GRAVITATIONAL_PARAMETER / ( MOON_GRAVITATIONAL_PARAMETER + EARTH_GRAVITATIONAL_PARAMETER) initial_conditions_file_path = '../../data/raw/orbits/L' + str( lagrange_point_nr) + '_' + orbit_type + '_initial_conditions.txt' initial_conditions_incl_m_df = load_initial_conditions_incl_M( initial_conditions_file_path) self.C = [] self.orbitDf = [] self.W_S_plus = [] self.W_S_min = [] self.W_U_plus = [] self.W_U_min = [] for c_level in reversed(sorted(orbit_id_per_c)): orbit_id = orbit_id_per_c[c_level] # self.C.append(initial_conditions_incl_m_df.iloc[orbit_id][0]) self.orbitDf.append( load_orbit('../../data/raw/orbits/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '.txt')) self.C.append( computeJacobiEnergy(self.orbitDf[-1].iloc[0]['x'], self.orbitDf[-1].iloc[0]['y'], self.orbitDf[-1].iloc[0]['z'], self.orbitDf[-1].iloc[0]['xdot'], self.orbitDf[-1].iloc[0]['ydot'], self.orbitDf[-1].iloc[0]['zdot'])) self.W_S_plus.append( load_manifold_refactored( '../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_S_plus.txt')) self.W_S_min.append( load_manifold_refactored( '../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_S_min.txt')) self.W_U_plus.append( load_manifold_refactored( '../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_U_plus.txt')) self.W_U_min.append( load_manifold_refactored( '../../data/raw/manifolds/refined_for_c/L' + str(lagrange_point_nr) + '_' + orbit_type + '_' + str(orbit_id) + '_W_U_min.txt')) self.numberOfOrbitsPerManifold = len( set(self.W_S_plus[0].index.get_level_values(0))) self.figSize = (7 * (1 + np.sqrt(5)) / 2, 7 * 2) blues = sns.color_palette('Blues', 100) greens = sns.color_palette('BuGn', 100) self.colorPaletteStable = sns.dark_palette( 'green', n_colors=self.numberOfOrbitsPerManifold) self.colorPaletteUnstable = sns.dark_palette( 'red', n_colors=self.numberOfOrbitsPerManifold) self.plottingColors = { 'lambda1': blues[40], 'lambda2': greens[50], 'lambda3': blues[90], 'lambda4': blues[90], 'lambda5': greens[70], 'lambda6': blues[60], 'singleLine': blues[80], 'doubleLine': [greens[50], blues[80]], 'tripleLine': [blues[40], greens[50], blues[80]], 'W_S_plus': self.colorPaletteStable[90], 'W_S_min': self.colorPaletteStable[40], 'W_U_plus': self.colorPaletteUnstable[90], 'W_U_min': self.colorPaletteUnstable[40], 'limit': 'black', 'orbit': 'navy' } self.suptitleSize = 20 pass
def plot_horizontal_to_halo(self): fig = plt.figure(figsize=self.figSize) ax1 = fig.add_subplot(2, 2, 1, projection='3d') ax2 = fig.add_subplot(2, 2, 2) ax3 = fig.add_subplot(2, 2, 3) ax4 = fig.add_subplot(2, 2, 4) horizontal_color = self.plottingColors['tripleLine'][2] halo_color = self.plottingColors['tripleLine'][0] # Plot bifurcations line_width = 2 plot_alpha = 1 df = load_orbit('../../data/raw/orbits/L1_horizontal_' + str(self.horizontalBifurcations[0]) + '.txt') l1, = ax1.plot(df['x'], df['y'], df['z'], color=horizontal_color, alpha=plot_alpha, linewidth=1, label='Horizontal Lyapunov') ax1.plot(df['x'], df['y'], df['z'], color=horizontal_color, alpha=plot_alpha, linewidth=line_width) ax2.plot(df['x'], df['y'], color=horizontal_color, alpha=plot_alpha, linewidth=line_width) ax3.plot(df['y'], df['z'], color=horizontal_color, alpha=plot_alpha, linewidth=line_width) ax4.plot(df['x'], df['z'], color=horizontal_color, alpha=plot_alpha, linewidth=line_width) number_of_orbits = 10 line_width = 1 plot_alpha = 0.5 for i in [ int(i) for i in (np.linspace(1, self.haloMaxId, number_of_orbits)) ]: df = load_orbit('../../data/raw/orbits/L1_halo_' + str(i) + '.txt') l2, = ax1.plot(df['x'], df['y'], df['z'], color=halo_color, alpha=plot_alpha, linewidth=line_width, label='Halo') ax2.plot(df['x'], df['y'], color=halo_color, alpha=plot_alpha, linewidth=line_width) ax3.plot(df['y'], df['z'], color=halo_color, alpha=plot_alpha, linewidth=line_width) ax4.plot(df['x'], df['z'], color=halo_color, alpha=plot_alpha, linewidth=line_width) # Lagrange points and bodies lagrange_points_df = load_lagrange_points_location() lagrange_point_nrs = ['L1', 'L2'] for lagrange_point_nr in lagrange_point_nrs: ax1.scatter(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['y'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x') ax2.scatter(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['y'], color='black', marker='x') ax3.scatter(lagrange_points_df[lagrange_point_nr]['y'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x') ax4.scatter(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x') bodies_df = load_bodies_location() u = np.linspace(0, 2 * np.pi, 100) v = np.linspace(0, np.pi, 100) for body in ['Moon']: x = bodies_df[body]['r'] * np.outer( np.cos(u), np.sin(v)) + bodies_df[body]['x'] y = bodies_df[body]['r'] * np.outer(np.sin(u), np.sin(v)) z = bodies_df[body]['r'] * np.outer(np.ones(np.size(u)), np.cos(v)) ax1.plot_surface(x, y, z, color='black') ax2.contourf(x, y, z, colors='black') ax3.contourf(y, z, x, colors='black') ax4.contourf(x, z, y, colors='black') ax1.set_xlabel('x [-]') ax1.set_ylabel('y [-]') ax1.set_zlabel('z [-]') ax1.grid(True, which='both', ls=':') ax2.set_xlabel('x [-]') ax2.set_ylabel('y [-]') ax2.grid(True, which='both', ls=':') ax3.set_xlabel('y [-]') ax3.set_ylabel('z [-]') ax3.grid(True, which='both', ls=':') ax4.set_xlabel('x [-]') ax4.set_ylabel('z [-]') ax4.grid(True, which='both', ls=':') plt.tight_layout() plt.subplots_adjust(top=0.9) ax1.legend(frameon=True, handles=[l1, l2]) plt.suptitle( '$L_1$ Bifurcation - Halo family connecting to horizontal Lyapunov orbits', size=self.suptitleSize) plt.savefig('../../data/figures/orbits/L1_bifurcation_halo.pdf', transparent=True) plt.close() pass
def animate(self): fig = plt.figure() ax = fig.add_subplot(111, projection='3d') self.W_S_plus = [load_manifold('../../../data/raw/manifolds/L' + str(1) + '_' + self.orbitType + '_' + str(self.orbitIds[0]) + '_W_S_plus.txt'), load_manifold('../../../data/raw/manifolds/L' + str(2) + '_' + self.orbitType + '_' + str(self.orbitIds[1]) + '_W_S_plus.txt')] self.W_S_min = [load_manifold('../../../data/raw/manifolds/L' + str(1) + '_' + self.orbitType + '_' + str(self.orbitIds[0]) + '_W_S_min.txt'), load_manifold('../../../data/raw/manifolds/L' + str(2) + '_' + self.orbitType + '_' + str(self.orbitIds[1]) + '_W_S_min.txt')] self.W_U_plus = [load_manifold('../../../data/raw/manifolds/L' + str(1) + '_' + self.orbitType + '_' + str(self.orbitIds[0]) + '_W_U_plus.txt'), load_manifold('../../../data/raw/manifolds/L' + str(2) + '_' + self.orbitType + '_' + str(self.orbitIds[1]) + '_W_U_plus.txt')] self.W_U_min = [load_manifold('../../../data/raw/manifolds/L' + str(1) + '_' + self.orbitType + '_' + str(self.orbitIds[0]) + '_W_U_min.txt'), load_manifold('../../../data/raw/manifolds/L' + str(2) + '_' + self.orbitType + '_' + str(self.orbitIds[1]) + '_W_U_min.txt')] self.numberOfOrbitsPerManifold = len(set(self.W_S_plus[0].index.get_level_values(0))) color_palette_green = sns.dark_palette('green', n_colors=self.numberOfOrbitsPerManifold) color_palette_red = sns.dark_palette('red', n_colors=self.numberOfOrbitsPerManifold) self.lines = [plt.plot([], [], color=color_palette_red[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)] self.lines.extend([plt.plot([], [], color=color_palette_green[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)]) self.lines.extend([plt.plot([], [], color=color_palette_red[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)]) self.lines.extend([plt.plot([], [], color=color_palette_green[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)]) self.lines.extend([plt.plot([], [], color=color_palette_red[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)]) self.lines.extend([plt.plot([], [], color=color_palette_green[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)]) self.lines.extend([plt.plot([], [], color=color_palette_green[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)]) self.lines.extend([plt.plot([], [], color=color_palette_red[idx], alpha=self.orbitAlpha)[0] for idx in range(self.numberOfOrbitsPerManifold)]) # Text object to display absolute normalized time of trajectories within the manifolds self.timeText = ax.text2D(0.05, 0.05, s='$\|t\| \\approx 0$', transform=ax.transAxes, size=self.timeTextSize) # Plot zero velocity surface x_range = np.arange(self.xLim[0], self.xLim[1], 0.001) y_range = np.arange(self.yLim[0], self.yLim[1], 0.001) x_mesh, y_mesh = np.meshgrid(x_range, y_range) z_mesh = cr3bp_velocity(x_mesh, y_mesh, c_level) if z_mesh.min() < 0: plt.contour(x_mesh, y_mesh, z_mesh, [z_mesh.min(), 0], colors='black', alpha=0.3) # Plot both orbits for k in range(2): orbit_df = load_orbit('../../../data/raw/orbits/L' + str(k+1) + '_' + self.orbitType + '_' + str(self.orbitIds[k]) + '.txt') plt.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color=self.orbitColor, alpha=self.orbitAlpha, linewidth=self.orbitLinewidth) # Plot both primaries u = np.linspace(0, 2 * np.pi, 100) v = np.linspace(0, np.pi, 100) bodies_df = load_bodies_location() for body in bodies_df: x = bodies_df[body]['r'] * np.outer(np.cos(u), np.sin(v)) + bodies_df[body]['x'] y = bodies_df[body]['r'] * np.outer(np.sin(u), np.sin(v)) z = bodies_df[body]['r'] * np.outer(np.ones(np.size(u)), np.cos(v)) ax.plot_surface(x, y, z, color='black') # Plot Lagrange points 1 and 2 lagrange_points_df = load_lagrange_points_location() lagrange_point_nrs = ['L1', 'L2'] for lagrange_point_nr in lagrange_point_nrs: ax.scatter3D(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['y'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x', s=self.lagrangePointMarkerSize) title = self.orbitTypeForTitle + ' $\{ \mathcal{W}^{S \pm}, \mathcal{W}^{U \pm} \}$ - Spatial overview at C = ' + str(c_level) ax.set_xlim3d(self.xLim) ax.set_ylim3d(self.yLim) ax.set_zlim3d(self.zLim) ax.set_xlabel('x [-]') ax.set_ylabel('y [-]') ax.set_zlabel('z [-]') ax.grid(True, which='both', ls=':') fig.tight_layout() fig.subplots_adjust(top=0.9) plt.suptitle(title, size=self.suptitleSize) # Fix overlap between labels and ticks ax.xaxis._axinfo['label']['space_factor'] = 6.0 ax.yaxis._axinfo['label']['space_factor'] = 6.0 ax.zaxis._axinfo['label']['space_factor'] = 6.0 # Determine the maximum value of t t_max = 0 for lagrange_point_idx in [0, 1]: for index in range(self.numberOfOrbitsPerManifold): t_max = max(t_max, abs(self.W_S_plus[lagrange_point_idx].xs(index).tail(1).index.values[0])) t_max = max(t_max, abs(self.W_S_min[lagrange_point_idx].xs(index).tail(1).index.values[0])) t_max = max(t_max, abs(self.W_U_plus[lagrange_point_idx].xs(index).tail(1).index.values[0])) t_max = max(t_max, abs(self.W_U_min[lagrange_point_idx].xs(index).tail(1).index.values[0])) print('Maximum value for t = ' + str(t_max) + ', animation t: = ') # Introduce a new time-vector for linearly spaced time throughout the animation self.t = np.linspace(0, t_max, np.round(t_max / 0.04) + 1) animation_function = animation.FuncAnimation(fig, self.update_lines, init_func=self.initiate_lines, frames=len(self.t), interval=1, blit=True) # # # Determine the maximum number of frames # number_of_frames = 0 # for lagrange_point_idx in [0, 1]: # for index in range(self.numberOfOrbitsPerManifold): # number_of_frames = max(number_of_frames, len(self.W_S_plus[lagrange_point_idx].xs(index)['x'])) # number_of_frames = max(number_of_frames, len(self.W_S_min[lagrange_point_idx].xs(index)['x'])) # number_of_frames = max(number_of_frames, len(self.W_U_plus[lagrange_point_idx].xs(index)['x'])) # number_of_frames = max(number_of_frames, len(self.W_U_min[lagrange_point_idx].xs(index)['x'])) # # animation_function = animation.FuncAnimation(fig, self.update_lines, init_func=self.initiate_lines, # frames=int(number_of_frames), interval=1, blit=True) empty_writer_object = animation.writers['ffmpeg'] animation_writer = empty_writer_object(fps=30, metadata=dict(artist='Koen Langemeijer')) file_name = '../../../data/animations/manifolds/spatial_manifolds_' + orbit_type + '_' + str(c_level) + '.mp4' animation_function.save(file_name, writer=animation_writer)
def animate(self): color_palette_green = sns.dark_palette( 'green', n_colors=self.numberOfOrbitsPerManifold) color_palette_red = sns.dark_palette( 'red', n_colors=self.numberOfOrbitsPerManifold) self.lines = [ self.ax.plot([], [], color='red', linewidth=self.orbitLinewidth, alpha=self.orbitAlpha)[0], self.ax.plot([], [], color='green', linewidth=self.orbitLinewidth, alpha=self.orbitAlpha)[0] ] # Text object to display absolute normalized time of trajectories within the manifolds self.timeText = self.ax.text2D(0.05, 0.05, s='$\|t\| \\approx 0$', transform=self.ax.transAxes, size=self.timeTextSize) # Plot zero velocity surface x_range = np.arange(self.xLim[0], self.xLim[1], 0.001) y_range = np.arange(self.yLim[0], self.yLim[1], 0.001) x_mesh, y_mesh = np.meshgrid(x_range, y_range) z_mesh = cr3bp_velocity(x_mesh, y_mesh, self.cLevel) if z_mesh.min() < 0: # plt.contour(x_mesh, y_mesh, z_mesh, [z_mesh.min(), 0], colors='black', alpha=0.3) self.ax.contour(x_mesh, y_mesh, z_mesh, list(np.linspace(z_mesh.min(), 0, 10)), cmap='gist_gray_r', alpha=0.5) # Plot both orbits for k in range(2): orbit_df = load_orbit( '../../../data/raw/orbits/refined_for_c/L' + str(k + 1) + '_' + self.orbitType + '_' + str(self.orbitIds[self.orbitType][k + 1][self.cLevel]) + '.txt') self.ax.plot(orbit_df['x'], orbit_df['y'], orbit_df['z'], color=self.orbitColor, alpha=self.orbitAlpha, linewidth=2, linestyle=':') # Plot both primaries u = np.linspace(0, 2 * np.pi, 100) v = np.linspace(0, np.pi, 100) bodies_df = load_bodies_location() for body in bodies_df: x = bodies_df[body]['r'] * np.outer( np.cos(u), np.sin(v)) + bodies_df[body]['x'] y = bodies_df[body]['r'] * np.outer(np.sin(u), np.sin(v)) z = bodies_df[body]['r'] * np.outer(np.ones(np.size(u)), np.cos(v)) self.ax.plot_surface(x, y, z, color='black') # Plot Lagrange points 1 and 2 lagrange_points_df = load_lagrange_points_location() lagrange_point_nrs = ['L1', 'L2'] for lagrange_point_nr in lagrange_point_nrs: self.ax.scatter3D(lagrange_points_df[lagrange_point_nr]['x'], lagrange_points_df[lagrange_point_nr]['y'], lagrange_points_df[lagrange_point_nr]['z'], color='black', marker='x', s=self.lagrangePointMarkerSize) title = self.orbitTypeForTitle + ' $\{ \mathcal{W}^{S \pm}, \mathcal{W}^{U \pm} \}$ - Orthographic projection (C = ' + str( self.cLevel) + ')' self.ax.set_xlim(self.xLim) self.ax.set_ylim(self.yLim) self.ax.set_zlim(self.zLim) self.ax.set_xlabel('x [-]') self.ax.set_ylabel('y [-]') self.ax.set_zlabel('z [-]') self.ax.grid(True, which='both', ls=':') # self.fig.tight_layout() self.fig.subplots_adjust(top=0.9) self.fig.suptitle(title, size=self.suptitleSize) # Fix overlap between labels and ticks self.ax.xaxis._axinfo['label']['space_factor'] = 6.0 self.ax.yaxis._axinfo['label']['space_factor'] = 6.0 self.ax.zaxis._axinfo['label']['space_factor'] = 6.0 # Determine the maximum value of t t_max = max(abs(self.W_U_plus.index)) + max(abs(self.W_S_min.index)) print('Maximum value for unstable = ' + str(max(abs(self.W_U_plus.index)))) print('Maximum value for stable = ' + str(max(abs(self.W_S_min.index)))) print('Maximum value for t = ' + str(t_max) + ', animation t: = ') # Introduce a new time-vector for linearly spaced time throughout the animation self.t = np.linspace(0, t_max, 150) self.animation_function = animation.FuncAnimation( self.fig, self.update_lines, init_func=self.initiate_lines, frames=len(self.t), interval=1, blit=True) self.empty_writer_object = animation.writers['ffmpeg'] self.animation_writer = self.empty_writer_object( fps=30, metadata=dict(artist='Koen Langemeijer')) self.file_name = '../../../data/animations/natural_connections/spatial_heteroclinic_' + self.orbitType + '_' + str( int(self.theta)) + '.mp4' self.animation_function.save(self.file_name, writer=self.animation_writer)