def plot_residuals(self): """ Make a plot of residuals and RV trend in the current Axes. """ ax = pl.gca() ax.plot(self.mplttimes, self.slope, 'b-', lw=self.fit_linewidth) plot.mtelplot(self.plttimes, self.resid, self.rverr, self.post.likelihood.telvec, ax, telfmts=self.telfmts) if not self.yscale_auto: scale = np.std(self.resid) ax.set_ylim(-self.yscale_sigma * scale, self.yscale_sigma * scale) if self.highlight_last: ind = np.argmax(self.plttimes) pl.plot(self.plttimes[ind], self.resid[ind], **plot.highlight_format) if self.set_xlim is not None: ax.set_xlim(self.set_xlim) else: ax.set_xlim( min(self.plttimes) - 0.01 * self.dt, max(self.plttimes) + 0.01 * self.dt) ticks = ax.yaxis.get_majorticklocs() ax.yaxis.set_ticks([ticks[0], 0.0, ticks[-1]]) pl.xlabel('JD - {:d}'.format(int(np.round(self.epoch))), weight='bold') ax.set_ylabel('Residuals', weight='bold') ax.yaxis.set_major_locator(MaxNLocator(5, prune='both'))
def plot_timeseries(self): """ Make a plot of the RV data and model in the current Axes. """ ax = pl.gca() ax.axhline(0, color='0.5', linestyle='--') if self.show_rms: rms_values = dict() for like in self.like_list: inst = like.suffix rms = np.std(like.residuals()) rms_values[inst] = rms else: rms_values = False # plot orbit model ax.plot(self.mplttimes, self.orbit_model, 'b-', rasterized=False, lw=self.fit_linewidth) # plot data vels = self.rawresid+self.rvmod plot.mtelplot( # data = residuals + model self.plttimes, vels, self.rverr, self.post.likelihood.telvec, ax, telfmts=self.telfmts, rms_values=rms_values ) if self.set_xlim is not None: ax.set_xlim(self.set_xlim) else: ax.set_xlim(min(self.plttimes)-0.01*self.dt, max(self.plttimes)+0.01*self.dt) pl.setp(ax.get_xticklabels(), visible=False) if self.highlight_last: ind = np.argmax(self.plttimes) pl.plot(self.plttimes[ind], vels[ind], **plot.highlight_format) # legend if self.legend: ax.legend(numpoints=1, **self.legend_kwargs) # years on upper axis axyrs = ax.twiny() xl = np.array(list(ax.get_xlim())) + self.epoch decimalyear = Time(xl, format='jd', scale='utc').decimalyear # axyrs.plot(decimalyear, decimalyear) axyrs.get_xaxis().get_major_formatter().set_useOffset(False) axyrs.set_xlim(*decimalyear) axyrs.set_xlabel('Year', fontweight='bold') pl.locator_params(axis='x', nbins=5) if not self.yscale_auto: scale = np.std(self.rawresid+self.rvmod) ax.set_ylim(-self.yscale_sigma * scale, self.yscale_sigma * scale) ax.set_ylabel('RV [{ms:}]'.format(**plot.latex), weight='bold') ticks = ax.yaxis.get_majorticklocs() ax.yaxis.set_ticks(ticks[1:])
def plot_timeseries(self): """ Make a plot of the RV data and model in the current Axes. """ ax = pl.gca() ax.axhline(0, color='0.5', linestyle='--') # plot orbit model ax.plot(self.mplttimes, self.orbit_model, 'b-', rasterized=False, lw=self.fit_linewidth) # plot data plot.mtelplot( # data = residuals + model self.plttimes, self.rawresid + self.rvmod, self.rverr, self.post.likelihood.telvec, ax, telfmts=self.telfmts) if self.set_xlim is not None: ax.set_xlim(self.set_xlim) else: ax.set_xlim( min(self.plttimes) - 0.01 * self.dt, max(self.plttimes) + 0.01 * self.dt) pl.setp(ax.get_xticklabels(), visible=False) # legend if self.legend: ax.legend(numpoints=1, loc='best') # years on upper axis axyrs = ax.twiny() xl = np.array(list(ax.get_xlim())) + self.epoch decimalyear = Time(xl, format='jd', scale='utc').decimalyear # axyrs.plot(decimalyear, decimalyear) axyrs.get_xaxis().get_major_formatter().set_useOffset(False) axyrs.set_xlim(*decimalyear) axyrs.set_xlabel('Year', fontweight='bold') if not self.yscale_auto: scale = np.std(self.rawresid + self.rvmod) ax.set_ylim(-self.yscale_sigma * scale, self.yscale_sigma * scale) ax.set_ylabel('RV [{ms:}]'.format(**plot.latex), weight='bold') ticks = ax.yaxis.get_majorticklocs() ax.yaxis.set_ticks(ticks[1:])
def plot_timeseries(self): """ Make a plot of the RV data and Gaussian Process + orbit model in the current Axes. """ ax = pl.gca() ax.axhline(0, color='0.5', linestyle='--') if self.subtract_orbit_model: orbit_model4data = np.zeros(self.rvmod.shape) else: orbit_model4data = self.rvmod ci = 0 for like in self.like_list: ci = self.plot_gp_like(like, orbit_model4data, ci) # plot data plot.mtelplot( # data = residuals + model self.plttimes, self.rawresid + orbit_model4data, self.rverr, self.post.likelihood.telvec, ax, telfmts=self.telfmts) if self.set_xlim is not None: ax.set_xlim(self.set_xlim) else: ax.set_xlim( min(self.plttimes) - 0.01 * self.dt, max(self.plttimes) + 0.01 * self.dt) pl.setp(ax.get_xticklabels(), visible=False) # legend if self.legend: ax.legend(numpoints=1, **self.legend_kwargs) # years on upper axis axyrs = ax.twiny() xl = np.array(list(ax.get_xlim())) + self.epoch decimalyear = Time(xl, format='jd', scale='utc').decimalyear axyrs.plot(decimalyear, decimalyear) axyrs.get_xaxis().get_major_formatter().set_useOffset(False) axyrs.set_xlim(*decimalyear) pl.locator_params(axis='x', nbins=5) axyrs.set_xlabel('Year', fontweight='bold')
def plot_multipanel(self, nophase=False): """ Provision and plot an RV multipanel plot for a Posterior object containing one or more Gaussian Process Likelihood objects. Args: nophase (bool, optional): if True, don't include phase plots. Default: False. Returns: tuple containing: - current matplotlib Figure object - list of Axes objects """ if not self.plot_likelihoods_separately: super(GPMultipanelPlot, self).plot_multipanel() else: if nophase: scalefactor = 1 else: scalefactor = self.phase_nrows n_likes = len(self.like_list) figheight = self.ax_rv_height * ( n_likes + 0.5) + self.ax_phase_height * scalefactor # provision figure fig = pl.figure(figsize=(self.figwidth, figheight)) fig.subplots_adjust(left=0.12, right=0.95) hrs = np.zeros(n_likes + 1) + 1. hrs[-1] = 0.5 gs_rv = gridspec.GridSpec(n_likes + 1, 1, height_ratios=hrs) divide = 1 - self.ax_rv_height * len(self.like_list) / figheight gs_rv.update(left=0.12, right=0.93, top=0.93, bottom=divide + self.rv_phase_space * 0.5, hspace=0.0) # orbit plot for each likelihood pltletter = ord('a') i = 0 ci = 0 for like in self.like_list: ax = pl.subplot(gs_rv[i, 0]) i += 1 self.ax_list += [ax] pl.sca(ax) ax.axhline(0, color='0.5', linestyle='--') if self.subtract_orbit_model: orbit_model4data = np.zeros(self.rvmod.shape) else: orbit_model4data = self.rvmod self.plot_gp_like(like, orbit_model4data, ci) # plot data plot.mtelplot( # data = residuals + model self.plttimes, self.rawresid + orbit_model4data, self.rverr, self.post.likelihood.telvec, ax, telfmts=self.telfmts) ax.set_xlim( min(self.plttimes) - 0.01 * self.dt, max(self.plttimes) + 0.01 * self.dt) pl.setp(ax.get_xticklabels(), visible=False) # legend if self.legend and i == 1: ax.legend(numpoints=1, **self.legend_kwargs) # years on upper axis if i == 1: axyrs = ax.twiny() xl = np.array(list(ax.get_xlim())) + self.epoch decimalyear = Time(xl, format='jd', scale='utc').decimalyear axyrs.plot(decimalyear, decimalyear) axyrs.get_xaxis().get_major_formatter().set_useOffset( False) axyrs.set_xlim(*decimalyear) axyrs.set_xlabel('Year', fontweight='bold') plot.labelfig(pltletter) pltletter += 1 # residuals ax_resid = pl.subplot(gs_rv[-1, 0]) self.ax_list += [ax_resid] pl.sca(ax_resid) self.plot_residuals() plot.labelfig(pltletter) pltletter += 1 # phase-folded plots if not nophase: gs_phase = gridspec.GridSpec(self.phase_nrows, self.phase_ncols) if self.phase_ncols == 1: gs_phase.update(left=0.12, right=0.93, top=divide - self.rv_phase_space * 0.5, bottom=0.07, hspace=0.003) else: gs_phase.update(left=0.12, right=0.93, top=divide - self.rv_phase_space * 0.5, bottom=0.07, hspace=0.25, wspace=0.25) for i in range(self.num_planets): i_row = int(i / self.phase_ncols) i_col = int(i - i_row * self.phase_ncols) ax_phase = pl.subplot(gs_phase[i_row, i_col]) self.ax_list += [ax_phase] pl.sca(ax_phase) self.plot_phasefold(pltletter, i + 1) pltletter += 1 if self.saveplot is not None: pl.savefig(self.saveplot, dpi=150) print("RV multi-panel plot saved to %s" % self.saveplot) return fig, self.ax_list
def plot_phasefold(self, pltletter, pnum): """ Plot phased orbit plots for each planet in the fit. Args: pltletter (int): integer representation of letter to be printed in the corner of the first phase plot. Ex: ord("a") gives 97, so the input should be 97. pnum (int): the number of the planet to be plotted. Must be the same as the number used to define a planet's Parameter objects (e.g. 'per1' is for planet #1) """ ax = pl.gca() if len(self.post.likelihood.x) < 20: self.nobin = True bin_fac = 1.75 bin_markersize = bin_fac * rcParams['lines.markersize'] bin_markeredgewidth = bin_fac * rcParams['lines.markeredgewidth'] rvmod2 = self.model(self.rvmodt, planet_num=pnum) - self.slope modph = t_to_phase(self.post.params, self.rvmodt, pnum, cat=True) - 1 rvdat = self.rawresid + self.model(self.rvtimes, planet_num=pnum) - self.slope_low phase = t_to_phase(self.post.params, self.rvtimes, pnum, cat=True) - 1 rvdatcat = np.concatenate((rvdat, rvdat)) rverrcat = np.concatenate((self.rverr, self.rverr)) rvmod2cat = np.concatenate((rvmod2, rvmod2)) bint, bindat, binerr = fastbin(phase + 1, rvdatcat, nbins=25) bint -= 1.0 ax.axhline( 0, color='0.5', linestyle='--', ) ax.plot(sorted(modph), rvmod2cat[np.argsort(modph)], 'b-', linewidth=self.fit_linewidth) plot.labelfig(pltletter) telcat = np.concatenate( (self.post.likelihood.telvec, self.post.likelihood.telvec)) if self.highlight_last: ind = np.argmax(self.rvtimes) hphase = t_to_phase(self.post.params, self.rvtimes[ind], pnum, cat=False) if hphase > 0.5: hphase -= 1 pl.plot(hphase, rvdatcat[ind], **plot.highlight_format) plot.mtelplot(phase, rvdatcat, rverrcat, telcat, ax, telfmts=self.telfmts) if not self.nobin and len(rvdat) > 10: ax.errorbar(bint, bindat, yerr=binerr, fmt='ro', mec='w', ms=bin_markersize, mew=bin_markeredgewidth) if self.phase_limits: ax.set_xlim(self.phase_limits[0], self.phase_limits[1]) else: ax.set_xlim(-0.5, 0.5) if not self.yscale_auto: scale = np.std(rvdatcat) ax.set_ylim(-self.yscale_sigma * scale, self.yscale_sigma * scale) keys = [p + str(pnum) for p in ['per', 'k', 'e']] labels = [self.post.params.tex_labels().get(k, k) for k in keys] if pnum < self.num_planets: ticks = ax.yaxis.get_majorticklocs() ax.yaxis.set_ticks(ticks[1:-1]) ax.set_ylabel('RV [{ms:}]'.format(**plot.latex), weight='bold') ax.set_xlabel('Phase', weight='bold') print_params = ['per', 'k', 'e'] units = {'per': 'days', 'k': plot.latex['ms'], 'e': ''} anotext = [] for l, p in enumerate(print_params): val = self.post.params["%s%d" % (print_params[l], pnum)].value if self.uparams is None: _anotext = r'$\mathregular{%s}$ = %4.2f %s' % ( labels[l].replace("$", ""), val, units[p]) else: if hasattr(self.post, 'medparams'): val = self.post.medparams["%s%d" % (print_params[l], pnum)] else: print("WARNING: medparams attribute not found in " + "posterior object will annotate with " + "max-likelihood values and reported uncertainties " + "may not be appropriate.") err = self.uparams["%s%d" % (print_params[l], pnum)] if err > 1e-15: val, err, errlow = sigfig(val, err) _anotext = r'$\mathregular{%s}$ = %s $\mathregular{\pm}$ %s %s' \ % (labels[l].replace("$", ""), val, err, units[p]) else: _anotext = r'$\mathregular{%s}$ = %4.2f %s' % ( labels[l].replace("$", ""), val, units[p]) anotext += [_anotext] if hasattr(self.post, 'derived'): chains = pd.read_csv(self.status['derive']['chainfile']) self.post.nplanets = self.num_planets dp = mcmc_plots.DerivedPlot(chains, self.post) labels = dp.labels texlabels = dp.texlabels units = dp.units derived_params = ['mpsini'] for l, par in enumerate(derived_params): par_label = par + str(pnum) if par_label in self.post.derived.columns: index = np.where(np.array(labels) == par_label)[0][0] unit = units[index] if unit == "M$_{\\rm Jup}$": conversion_fac = 0.00315 elif unit == "M$_{\\odot}$": conversion_fac = 0.000954265748 else: conversion_fac = 1 val = self.post.derived["%s%d" % (derived_params[l], pnum)].loc[0.500] * conversion_fac low = self.post.derived["%s%d" % (derived_params[l], pnum)].loc[0.159] * conversion_fac high = self.post.derived[ "%s%d" % (derived_params[l], pnum)].loc[0.841] * conversion_fac err_low = val - low err_high = high - val err = np.mean([err_low, err_high]) err = radvel.utils.round_sig(err) if err > 1e-15: val, err, errlow = sigfig(val, err) _anotext = r'$\mathregular{%s}$ = %s $\mathregular{\pm}$ %s %s' \ % (texlabels[index].replace("$", ""), val, err, units[index]) else: _anotext = r'$\mathregular{%s}$ = %4.2f %s' % ( texlabels[index].replace("$", ""), val, units[index]) anotext += [_anotext] anotext = '\n'.join(anotext) plot.add_anchored(anotext, loc=1, frameon=True, prop=dict(size=self.phasetext_size, weight='bold'), bbox=dict(ec='none', fc='w', alpha=0.8))
def plot_phasefold(self, pltletter, pnum): """ Plot phased orbit plots for each planet in the fit. Args: pltletter (int): integer representation of letter to be printed in the corner of the first phase plot. Ex: ord("a") gives 97, so the input should be 97. pnum (int): the number of the planet to be plotted. Must be the same as the number used to define a planet's Parameter objects (e.g. 'per1' is for planet #1) """ ax = pl.gca() if len(self.post.likelihood.x) < 20: self.nobin = True bin_fac = 1.75 bin_markersize = bin_fac * rcParams['lines.markersize'] bin_markeredgewidth = bin_fac * rcParams['lines.markeredgewidth'] rvmod2 = self.model(self.rvmodt, planet_num=pnum) - self.slope modph = t_to_phase(self.post.params, self.rvmodt, pnum, cat=True) - 1 rvdat = self.rawresid + self.model(self.rvtimes, planet_num=pnum) - self.slope_low phase = t_to_phase(self.post.params, self.rvtimes, pnum, cat=True) - 1 rvdatcat = np.concatenate((rvdat, rvdat)) rverrcat = np.concatenate((self.rverr, self.rverr)) rvmod2cat = np.concatenate((rvmod2, rvmod2)) bint, bindat, binerr = fastbin(phase + 1, rvdatcat, nbins=25) bint -= 1.0 ax.axhline( 0, color='0.5', linestyle='--', ) ax.plot(sorted(modph), rvmod2cat[np.argsort(modph)], 'b-', linewidth=self.fit_linewidth) plot.labelfig(pltletter) telcat = np.concatenate( (self.post.likelihood.telvec, self.post.likelihood.telvec)) plot.mtelplot(phase, rvdatcat, rverrcat, telcat, ax, telfmts=self.telfmts) if not self.nobin and len(rvdat) > 10: ax.errorbar(bint, bindat, yerr=binerr, fmt='ro', mec='w', ms=bin_markersize, mew=bin_markeredgewidth) if self.phase_limits: ax.set_xlim(self.phase_limits[0], self.phase_limits[1]) else: ax.set_xlim(-0.5, 0.5) if not self.yscale_auto: scale = np.std(rvdatcat) ax.set_ylim(-self.yscale_sigma * scale, self.yscale_sigma * scale) keys = [p + str(pnum) for p in ['per', 'k', 'e']] labels = [self.post.params.tex_labels().get(k, k) for k in keys] if pnum < self.num_planets: ticks = ax.yaxis.get_majorticklocs() ax.yaxis.set_ticks(ticks[1:-1]) ax.set_ylabel('RV [{ms:}]'.format(**plot.latex), weight='bold') ax.set_xlabel('Phase', weight='bold') print_params = ['per', 'k', 'e'] units = {'per': 'days', 'k': plot.latex['ms'], 'e': ''} anotext = [] for l, p in enumerate(print_params): val = self.post.params["%s%d" % (print_params[l], pnum)].value if self.uparams is None: _anotext = '$\\mathregular{%s}$ = %4.2f %s' % ( labels[l].replace("$", ""), val, units[p]) else: if hasattr(self.post, 'medparams'): val = self.post.medparams["%s%d" % (print_params[l], pnum)] else: print("WARNING: medparams attribute not found in " + "posterior object will annotate with " + "max-likelihood values and reported uncertainties " + "may not be appropriate.") err = self.uparams["%s%d" % (print_params[l], pnum)] if err > 0: val, err, errlow = sigfig(val, err) _anotext = '$\\mathregular{%s}$ = %s $\\mathregular{\\pm}$ %s %s' \ % (labels[l].replace("$", ""), val, err, units[p]) else: _anotext = '$\\mathregular{%s}$ = %4.2f %s' % ( labels[l].replace("$", ""), val, units[p]) anotext += [_anotext] anotext = '\n'.join(anotext) plot.add_anchored(anotext, loc=1, frameon=True, prop=dict(size=self.phasetext_size, weight='bold'), bbox=dict(ec='none', fc='w', alpha=0.8))