def plot(self, state, osculating=True, label=None): """Plots state and osculating orbit in their plane. """ # TODO: This function needs a refactoring if not self._frame: self.set_frame(*state.pqw()) self._states.append(state) lines = [] nu_vals = self._generate_vals(state) # Compute PQW coordinates r_pqw, _ = rv_pqw(state.attractor.k.to(u.km ** 3 / u.s ** 2).value, state.p.to(u.km).value, state.ecc.value, nu_vals.value) r_pqw = r_pqw * u.km # Express on inertial frame e_vec, p_vec, h_vec = state.pqw() p_vec = np.cross(h_vec, e_vec) * u.one rr = (r_pqw[:, 0, None].dot(e_vec[None, :]) + r_pqw[:, 1, None].dot(p_vec[None, :])) # Project on OrbitPlotter frame # x_vec, y_vec, z_vec = self._frame rr_proj = rr - rr.dot(self._frame[2])[:, None] * self._frame[2] x = rr_proj.dot(self._frame[0]) y = rr_proj.dot(self._frame[1]) # Plot current position l, = self.ax.plot(x[0].to(u.km).value, y[0].to(u.km).value, 'o', mew=0) lines.append(l) # Attractor self.ax.add_patch(mpl.patches.Circle((0, 0), state.attractor.R.to(u.km).value, lw=0, color='#204a87')) # Earth if osculating: l, = self.ax.plot(x.to(u.km).value, y.to(u.km).value, '--', color=l.get_color()) lines.append(l) if label: # This will apply the label to either the point or the osculating # orbit depending on the last plotted line, as they share variable l.set_label(label) self.ax.set_title(state.epoch.iso) self.ax.set_xlabel("$x$ (km)") self.ax.set_ylabel("$y$ (km)") self.ax.set_aspect(1) self.ax.legend() return lines
def plot(self, orbit, osculating=True, label=None): """Plots state and osculating orbit in their plane. """ # TODO: This function needs a refactoring if not self._frame: self.set_frame(*orbit.pqw()) # if new attractor radius is smaller, plot it new_radius = max(orbit.attractor.R.to(u.km).value, orbit.r_p.to(u.km).value / 6) if not self._attractor_radius: self.set_attractor(orbit) elif new_radius < self._attractor_radius: self.set_attractor(orbit) lines = [] nu_vals = self._generate_vals(orbit.state) # Compute PQW coordinates r_pqw, _ = rv_pqw(orbit.attractor.k.to(u.km ** 3 / u.s ** 2).value, orbit.p.to(u.km).value, orbit.ecc.value, nu_vals.value) r_pqw = r_pqw * u.km # Express on inertial frame e_vec, p_vec, h_vec = orbit.pqw() p_vec = np.cross(h_vec, e_vec) * u.one rr = (r_pqw[:, 0, None].dot(e_vec[None, :]) + r_pqw[:, 1, None].dot(p_vec[None, :])) # Project on OrbitPlotter frame # x_vec, y_vec, z_vec = self._frame rr_proj = rr - rr.dot(self._frame[2])[:, None] * self._frame[2] x = rr_proj.dot(self._frame[0]) y = rr_proj.dot(self._frame[1]) # Plot current position l, = self.ax.plot(x[0].to(u.km).value, y[0].to(u.km).value, 'o', mew=0) lines.append(l) if osculating: l, = self.ax.plot(x.to(u.km).value, y.to(u.km).value, '--', color=l.get_color()) lines.append(l) if label: # This will apply the label to either the point or the osculating # orbit depending on the last plotted line, as they share variable l.set_label(label) self.ax.legend() self.ax.set_title(orbit.epoch.iso) self.ax.set_xlabel("$x$ (km)") self.ax.set_ylabel("$y$ (km)") self.ax.set_aspect(1) return lines
def plot(self, orbit, label=None): """Plots state and osculating orbit in their plane. """ # TODO: This function needs a refactoring if not self._frame: self.set_frame(*orbit.pqw()) # if new attractor radius is smaller, plot it new_radius = max( orbit.attractor.R.to(u.km).value, orbit.r_p.to(u.km).value / 6) if not self._attractor_radius: self.set_attractor(orbit) elif new_radius < self._attractor_radius: self.set_attractor(orbit) lines = [] nu_vals = self._generate_vals(orbit.state) # Compute PQW coordinates r_pqw, _ = rv_pqw( orbit.attractor.k.to(u.km**3 / u.s**2).value, orbit.p.to(u.km).value, orbit.ecc.value, nu_vals.value) r_pqw = r_pqw * u.km # Express on inertial frame e_vec, p_vec, h_vec = orbit.pqw() p_vec = np.cross(h_vec, e_vec) * u.one rr = (r_pqw[:, 0, None].dot(e_vec[None, :]) + r_pqw[:, 1, None].dot(p_vec[None, :])) # Project on OrbitPlotter frame # x_vec, y_vec, z_vec = self._frame rr_proj = rr - rr.dot(self._frame[2])[:, None] * self._frame[2] x = rr_proj.dot(self._frame[0]) y = rr_proj.dot(self._frame[1]) # Plot current position l, = self.ax.plot(x[0].to(u.km).value, y[0].to(u.km).value, 'o', mew=0) lines.append(l) l, = self.ax.plot(x.to(u.km).value, y.to(u.km).value, '--', color=l.get_color()) lines.append(l) if label: # This will apply the label to either the point or the osculating # orbit depending on the last plotted line, as they share variable handles = [] # type: List[mpl.lines.Line2D] labels = [] # type: List[str] orbit.epoch.out_subfmt = 'date_hm' label = '{} ({})'.format(orbit.epoch.iso, label) legends = self.ax.figure.legends if legends: handles = legends[0].get_lines() labels = [text.get_text() for text in legends[0].get_texts()] legends[0].remove() handles.append(l) labels.append(label) self.ax.figure.legend(handles, labels, mode="expand", loc="lower center", fancybox=True, title="Names and epochs") self.ax.set_xlabel("$x$ (km)") self.ax.set_ylabel("$y$ (km)") self.ax.set_aspect(1) return lines
def plot(self, state, osculating=True): """Plots state and osculating orbit in their plane. """ if not self._frame: self.set_frame(*state.pqw()) self._states.append(state) lines = [] # Generate points of the osculating orbit if state.ecc >= 1.0: # Select a sensible limiting value for non-closed orbits. # This corresponds to r = 3p. max_nu = np.arccos(-(1 - 1 / 3.) / state.ecc).to(u.rad).value else: max_nu = np.pi # rad nu_vals = np.linspace(-max_nu, max_nu, self.num_points) # rad # Insert state true anomaly into array idx = np.searchsorted(nu_vals, state.nu.to(u.rad)) nu_vals = np.insert(nu_vals, idx, state.nu.to(u.rad).value) * u.rad # Compute PQW coordinates r_pqw, _ = rv_pqw(state.attractor.k.to(u.km ** 3 / u.s ** 2).value, state.p.to(u.km).value, state.ecc.value, nu_vals.value) r_pqw = r_pqw * u.km # Express on inertial frame e_vec, p_vec, h_vec = state.pqw() p_vec = np.cross(h_vec, e_vec) * u.one rr = (r_pqw[:, 0, None].dot(e_vec[None, :]) + r_pqw[:, 1, None].dot(p_vec[None, :])) # Project on OrbitPlotter frame # x_vec, y_vec, z_vec = self._frame rr_proj = rr - rr.dot(self._frame[2])[:, None] * self._frame[2] x = rr_proj.dot(self._frame[0]) y = rr_proj.dot(self._frame[1]) # Plot current position l, = self.ax.plot(x[idx].to(u.km).value, y[idx].to(u.km).value, 'o', mew=0) lines.append(l) # Attractor self.ax.add_patch(mpl.patches.Circle((0, 0), state.attractor.R.to(u.km).value, lw=0, color='#204a87')) # Earth if osculating: l, = self.ax.plot(x.to(u.km).value, y.to(u.km).value, '--', color=l.get_color()) lines.append(l) self.ax.set_title(state.epoch.iso) self.ax.set_xlabel("$x$ (km)") self.ax.set_ylabel("$y$ (km)") self.ax.set_aspect(1) return lines