def plot_model(self): """ Plot the star model. """ x = np.arange(self.x0 - 5 * self.fwhm, self.x0 + 5 * self.fwhm) y = np.arange(self.y0 - 5 * self.fwhm, self.y0 + 5 * self.fwhm) xx, yy = np.meshgrid(x, y) star = self.psf.evaluate(np.array([xx, yy])) fig, ax = plt.subplots(1, 1) plot_image_simple( ax, star, title=f'Star model: A={self.amplitude:.2f}, fwhm={self.fwhm:.2f}', units='Arbitrary units') if parameters.DISPLAY: plt.show() if parameters.PdfPages: parameters.PdfPages.savefig()
def plot_spectrogram_comparison_simple(self, ax, title='', extent=None, dispersion=False): """Method to plot a spectrogram issued from data and compare it with simulations. Parameters ---------- ax: Axes Axes instance of shape (4, 2). title: str, optional Title for the simulation plot (default: ''). extent: array_like, optional Extent argument for imshow to crop plots (default: None). dispersion: bool, optional If True, plot a colored bar to see the associated wavelength color along the x axis (default: False). """ lambdas = self.spectrum.lambdas sub = np.where((lambdas > parameters.LAMBDA_MIN) & (lambdas < parameters.LAMBDA_MAX))[0] sub = np.where(sub < self.spectrum.spectrogram_Nx)[0] if extent is not None: sub = np.where((lambdas > extent[0]) & (lambdas < extent[1]))[0] if len(sub) > 0: norm = np.max(self.data[:, sub]) plot_image_simple(ax[0, 0], data=self.data[:, sub] / norm, title='Data', aspect='auto', cax=ax[0, 1], vmin=0, vmax=1, units='1/max(data)') ax[0, 0].set_title('Data', fontsize=10, loc='center', color='white', y=0.8) plot_image_simple(ax[1, 0], data=self.model[:, sub] / norm, aspect='auto', cax=ax[1, 1], vmin=0, vmax=1, units='1/max(data)') if dispersion: x = self.spectrum.chromatic_psf.table['Dx'][sub[5:-5]] + self.spectrum.spectrogram_x0 - sub[0] y = np.ones_like(x) ax[1, 0].scatter(x, y, cmap=from_lambda_to_colormap(self.lambdas[sub[5:-5]]), edgecolors='None', c=self.lambdas[sub[5:-5]], label='', marker='o', s=10) # p0 = ax.plot(lambdas, self.model(lambdas), label='model') # # ax.plot(self.lambdas, self.model_noconv, label='before conv') if title != '': ax[1, 0].set_title(title, fontsize=10, loc='center', color='white', y=0.8) residuals = (self.data - self.model) # residuals_err = self.spectrum.spectrogram_err / self.model norm = self.err residuals /= norm std = float(np.std(residuals[:, sub])) plot_image_simple(ax[2, 0], data=residuals[:, sub], vmin=-5 * std, vmax=5 * std, title='(Data-Model)/Err', aspect='auto', cax=ax[2, 1], units='', cmap="bwr") ax[2, 0].set_title('(Data-Model)/Err', fontsize=10, loc='center', color='black', y=0.8) ax[2, 0].text(0.05, 0.05, f'mean={np.mean(residuals[:, sub]):.3f}\nstd={np.std(residuals[:, sub]):.3f}', horizontalalignment='left', verticalalignment='bottom', color='black', transform=ax[2, 0].transAxes) ax[0, 0].set_xticks(ax[2, 0].get_xticks()[1:-1]) ax[0, 1].get_yaxis().set_label_coords(3.5, 0.5) ax[1, 1].get_yaxis().set_label_coords(3.5, 0.5) ax[2, 1].get_yaxis().set_label_coords(3.5, 0.5) ax[3, 1].remove() ax[3, 0].plot(self.lambdas[sub], self.data.sum(axis=0)[sub], label='Data') ax[3, 0].plot(self.lambdas[sub], self.model.sum(axis=0)[sub], label='Model') ax[3, 0].set_ylabel('Cross spectrum') ax[3, 0].set_xlabel(r'$\lambda$ [nm]') ax[3, 0].legend(fontsize=7) ax[3, 0].grid(True)
def plot_model(self): xx, yy = np.mgrid[0:parameters.CCD_IMSIZE:1, 0:parameters.CCD_IMSIZE:1] starfield = self.model(xx, yy) fig, ax = plt.subplots(1, 1) plot_image_simple(ax, starfield, scale="log10", target_pixcoords=self.pixcoords) # im = plt.imshow(starfield, origin='lower', cmap='jet') # ax.grid(color='white', ls='solid') # ax.grid(True) # ax.set_xlabel('X [pixels]') # ax.set_ylabel('Y [pixels]') # ax.set_title(f'Star field model: fwhm={self.fwhm.value:.2f}') # cb = plt.colorbar(im, ax=ax) # cb.formatter.set_powerlimits((0, 0)) # cb.locator = MaxNLocator(7, prune=None) # cb.update_ticks() # cb.set_label('Arbitrary units') # ,fontsize=16) if parameters.DISPLAY: plt.show() if parameters.PdfPages: parameters.PdfPages.savefig()
def remove_image_background_sextractor(data, sigma=3.0, box_size=(50, 50), filter_size=(3, 3), positive=False): sigma_clip = SigmaClip(sigma=sigma) bkg_estimator = SExtractorBackground() bkg = Background2D(data, box_size, filter_size=filter_size, sigma_clip=sigma_clip, bkg_estimator=bkg_estimator) data_wo_bkg = data - bkg.background if positive: data_wo_bkg -= np.min(data_wo_bkg) if parameters.DEBUG: fig, ax = plt.subplots(1, 2, figsize=(11, 5)) plot_image_simple(ax[0], bkg.background, scale="lin") plot_image_simple(ax[1], data_wo_bkg, scale="symlog") fig.tight_layout() plt.show() if parameters.PdfPages: parameters.PdfPages.savefig() return data_wo_bkg
def plot_fit(self): if self.data.ndim == 1: fig, ax = plt.subplots(2, 1, figsize=(6, 6), sharex='all', gridspec_kw={'height_ratios': [5, 1]}) data = np.copy(self.data) if self.bgd_model_func is not None: data = data + self.bgd_model_func(self.pixels) ax[0].errorbar(self.pixels, data, yerr=self.err, fmt='ro', label="Data") if len(self.outliers) > 0: ax[0].errorbar(self.outliers, data[self.outliers], yerr=self.err[self.outliers], fmt='go', label=rf"Outliers ({self.sigma_clip}$\sigma$)") if self.bgd_model_func is not None: ax[0].plot(self.pixels, self.bgd_model_func(self.pixels), 'b--', label="fitted bgd") if self.guess is not None: if self.bgd_model_func is not None: ax[0].plot(self.pixels, self.psf.evaluate(self.pixels, p=self.guess) + self.bgd_model_func(self.pixels), 'k--', label="Guess") else: ax[0].plot(self.pixels, self.psf.evaluate(self.pixels, p=self.guess), 'k--', label="Guess") self.psf.p = np.copy(self.p) model = np.copy(self.model) # if self.bgd_model_func is not None: # model = self.model + self.bgd_model_func(self.pixels) ax[0].plot(self.pixels, model, 'b-', label="Model") ylim = list(ax[0].get_ylim()) ylim[1] = 1.2 * np.max(self.model) ax[0].set_ylim(ylim) ax[0].set_ylabel('Transverse profile') ax[0].legend(loc=2, numpoints=1) ax[0].grid(True) txt = "" for ip, p in enumerate(self.input_labels): txt += f'{p}: {self.p[ip]:.4g}\n' ax[0].text(0.95, 0.95, txt, horizontalalignment='right', verticalalignment='top', transform=ax[0].transAxes) # residuals residuals = (data - model) / self.err residuals_err = np.ones_like(self.err) ax[1].errorbar(self.pixels, residuals, yerr=residuals_err, fmt='ro') if len(self.outliers) > 0: residuals_outliers = (data[self.outliers] - model[self.outliers]) / self.err[self.outliers] residuals_outliers_err = np.ones_like(residuals_outliers) ax[1].errorbar(self.outliers, residuals_outliers, yerr=residuals_outliers_err, fmt='go') ax[1].axhline(0, color='b') ax[1].grid(True) std = np.std(residuals) ax[1].set_ylim([-3. * std, 3. * std]) ax[1].set_xlabel(ax[0].get_xlabel()) ax[1].set_ylabel('(data-fit)/err') ax[0].set_xticks(ax[1].get_xticks()[1:-1]) ax[0].get_yaxis().set_label_coords(-0.1, 0.5) ax[1].get_yaxis().set_label_coords(-0.1, 0.5) # fig.tight_layout() # fig.subplots_adjust(wspace=0, hspace=0) elif self.data.ndim == 2: gs_kw = dict(width_ratios=[3, 0.15], height_ratios=[1, 1, 1, 1]) fig, ax = plt.subplots(nrows=4, ncols=2, figsize=(5, 7), gridspec_kw=gs_kw) norm = np.nanmax(self.data) plot_image_simple(ax[0, 0], data=self.model / norm, aspect='auto', cax=ax[0, 1], vmin=0, vmax=1, units='1/max(data)') ax[0, 0].set_title("Model", fontsize=10, loc='center', color='white', y=0.8) plot_image_simple(ax[1, 0], data=self.data / norm, title='Data', aspect='auto', cax=ax[1, 1], vmin=0, vmax=1, units='1/max(data)') ax[1, 0].set_title('Data', fontsize=10, loc='center', color='white', y=0.8) residuals = (self.data - self.model) # residuals_err = self.spectrum.spectrogram_err / self.model norm = self.err residuals /= norm std = float(np.std(residuals)) plot_image_simple(ax[2, 0], data=residuals, vmin=-5 * std, vmax=5 * std, title='(Data-Model)/Err', aspect='auto', cax=ax[2, 1], units='', cmap="bwr") ax[2, 0].set_title('(Data-Model)/Err', fontsize=10, loc='center', color='black', y=0.8) ax[2, 0].text(0.05, 0.05, f'mean={np.mean(residuals):.3f}\nstd={np.std(residuals):.3f}', horizontalalignment='left', verticalalignment='bottom', color='black', transform=ax[2, 0].transAxes) ax[0, 0].set_xticks(ax[2, 0].get_xticks()[1:-1]) ax[0, 1].get_yaxis().set_label_coords(3.5, 0.5) ax[1, 1].get_yaxis().set_label_coords(3.5, 0.5) ax[2, 1].get_yaxis().set_label_coords(3.5, 0.5) ax[3, 1].remove() ax[3, 0].plot(np.arange(self.Nx), self.data.sum(axis=0), label='Data') ax[3, 0].plot(np.arange(self.Nx), self.model.sum(axis=0), label='Model') ax[3, 0].set_ylabel('Transverse sum') ax[3, 0].set_xlabel(r'X [pixels]') ax[3, 0].legend(fontsize=7) ax[3, 0].grid(True) else: raise ValueError(f"Data array must have dimension 1 or 2. Here data.ndim={self.data.ndim}.") if self.live_fit: # pragma: no cover plt.draw() plt.pause(1e-8) plt.close() else: if parameters.DISPLAY: plt.show() else: plt.close(fig) if parameters.SAVE: # pragma: no cover figname = os.path.splitext(self.filename)[0] + "_bestfit.pdf" self.my_logger.info(f"\n\tSave figure {figname}.") fig.savefig(figname, dpi=100, bbox_inches='tight') if parameters.PdfPages: parameters.PdfPages.savefig()