Source code for yieldplotlib.plots.yip_plots

"""Generate plots for yield input packages."""

import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np


[docs] def make_offax_psf_movie(yip, save_name, ax_kwargs=None, plot_kwargs=None): """Generate a movie of the off-axis stellar PSF moving as a function of lambda/D. Args: yip (YIPDirectory): YIPDirectory to plot. save_name (str): File path to where the output movie will be saved. ax_kwargs (dict, optional): Keyword arguments to pass to ax.set(). plot_kwargs (dict, optional): Keyword arguments to pass to plt.figure(). Returns: None """ # Get the off-axis stellar PSF data from the YIP. if plot_kwargs is None: plot_kwargs = {} if ax_kwargs is None: ax_kwargs = {} offax_psf_data = yip.get("offax.data") offax_psf_offsets_list = yip.get("offax_offset_list.data") # Set up the figure and axis. fig, ax = plt.subplots(**plot_kwargs) # Prepare the initial image. initial_image = np.log(offax_psf_data[0]) initial_image[~np.isfinite(initial_image)] = -20 ax.imshow(initial_image) fig.tight_layout() # Add an inset text with the current λ/D value. props = dict(boxstyle="round", facecolor="white", alpha=0.5) text_obj = ax.text( 0.95, 0.9, f"$\\lambda / D$ = {offax_psf_offsets_list[0]:.2f}", transform=ax.transAxes, fontsize=12, verticalalignment="bottom", horizontalalignment="right", bbox=props, ) # Apply any additional axis settings. ax.set(**ax_kwargs) # Update frames def update(frame): im_data = np.log(offax_psf_data[frame]) im_data[~np.isfinite(im_data)] = -20 im_obj = ax.imshow(im_data) # Update the text text_obj.set_text(f"$\\lambda / D$ = {offax_psf_offsets_list[frame]:.2f}") return im_obj, text_obj # Create the animation. ani = animation.FuncAnimation(fig, update, frames=len(offax_psf_data), blit=True) # Save the animation to file. ani.save(save_name, fps=2, writer="ffmpeg") plt.close(fig) return ani
[docs] def plot_core_throughtput( runs, run_labels, yip=None, ax=None, ax_kwargs=None, use_cyberpunk=False, title=None, aperture_radius=0.85, ): """Plot the core throughput as a function of lambda/D. Args: runs (list): List of EXOSIMSDirectories and AYODirectories to plot. run_labels (list): List of labels for each run. yip (YIPDirectory): YIPDirectory to plot. If None, the throughput directly from the YIP (accessed via yippy) will not be plotted. ax (matplotlib.axes.Axes, optional): Axes to plot on. If None, a new figure is created. ax_kwargs (dict, optional): Keyword arguments to pass to ax.set(). use_cyberpunk (bool, optional): Whether to use the mplcyberpunk style. Default is False. title (str, optional): Title for the plot. aperture_radius (float): Radius of the photometric aperture to use for the YIP throughput calculation. Returns: matplotlib.figure.Figure, matplotlib.axes.Axes: Figure and axes objects for the plot. """ if ax_kwargs is None: ax_kwargs = {} if use_cyberpunk: import mplcyberpunk from cycler import cycler plt.style.use("cyberpunk") prop_cycle = plt.rcParams["axes.prop_cycle"] colors = prop_cycle.by_key()["color"] custom_cycler = cycler(linestyle=["-", "--", ":", "-."]) + cycler( color=colors[:4] ) plt.rc("axes", prop_cycle=custom_cycler) if ax is None: fig, ax = plt.subplots() else: fig = ax.get_figure() if yip: performance_metrics = yip.coronagraph.compute_all_performance_curves( oversample=1, aperture_radius_lod=aperture_radius ) separations = performance_metrics["separations"] core_thruput_from_yip = performance_metrics["throughput"] ax.plot(separations, core_thruput_from_yip, label="yippy") for i, run in enumerate(runs): data = run.get("core_thruput") ax.plot(data["sep"], data["thruput"], label=f"{run_labels[i]}") ax.set(**ax_kwargs) plt.xlabel("Separation ($\\lambda/D$)") plt.ylabel("Throughput") plt.legend() if use_cyberpunk: mplcyberpunk.add_glow_effects() if title: plt.title(title) return fig, ax