# -*- coding: utf-8 -*-
import coplot.plots as pl
import coplot.plot_contours as plc
from . import space_updater as su
from . import cosmic_params
import numpy as np
import matplotlib.pyplot as plt
[docs]class BestFitsData(object):
#best fit values of each steps, used to plot steps in PlotPosterior
def __init__(self, chain_all, chain_ann, param_labels='', burnIn_step=None):
self.chain_all = chain_all
self.steps_n = len(self.chain_all)
self.chain_ann = chain_ann
self.param_labels = param_labels
self.burnIn_step = burnIn_step
@property
def bestFits_all(self):
best_ann = []
for i in range(self.steps_n):
best_ann.append(su.Chains.bestFit(self.chain_all[i], symmetry_error=False))
return np.array(best_ann)
@property
def best_fit(self):
return su.Chains.bestFit(self.chain_ann, symmetry_error=False)
[docs] def panel_data(self, p_index):
data = {'labels' : ['Steps', self.param_labels[p_index]]}
best_mean = self.best_fit[p_index][0]#
data['best_mean'] = best_mean
data['err_mean'] = [self.best_fit[p_index][1], self.best_fit[p_index][2]]
best_fits = self.bestFits_all[:, p_index, :]
data['bestFits'] = best_fits
y_max = max(best_fits[:,0] + best_fits[:,2])
y_min = min(best_fits[:,0] - best_fits[:,1])
dy = y_max - y_min
ylim_min = y_min - dy*0.1
if y_max-best_mean > 0.7*dy or y_max-best_mean < 0.3*dy:
ylim_max = y_max + dy*0.1
else:
ylim_max = y_max + dy*0.7
lims = [0, self.steps_n+1, ylim_min, ylim_max]
data['ylim_max'], data['ylim_min'] = ylim_max, ylim_min
data['lims'] = lims
data['steps_n'] = self.steps_n
return data
[docs] def panels_data(self):
datasets = []
for index in range(len(self.param_labels)):
data = self.panel_data(index)
data['burnIn_step'] = self.burnIn_step
datasets.append(data)
return datasets
[docs] def panel(self, data):
#ann
plt.errorbar(range(1, data['steps_n']+1), data['bestFits'][:,0], yerr=[data['bestFits'][:,1],data['bestFits'][:,2]], fmt='o', color='r', label='ANN')
#burn-in
if data['burnIn_step'] is not None:
plt.plot([data['burnIn_step']+0.5, data['burnIn_step']+0.5], [data['ylim_min'], data['ylim_max']], '--', color='grey', label='Burn-in', lw=2)
#mean values
plt.plot([0, data['steps_n']+1], [data['best_mean'], data['best_mean']], 'k-', label='Best-fit', lw=2)
plt.fill_between([0, data['steps_n']+1], data['best_mean']-data['err_mean'][0], data['best_mean']+data['err_mean'][1], color='grey', alpha=0.3)
plt.legend(fontsize=12)
#to be updated based on ann.ANN???
[docs]class PlotPosterior(object):
def __init__(self, chain_all, chain_ann, param_names, params_dict=None,
burnIn_step=None, randn_num='', path='ann'):
self.chain_all = chain_all
self.steps_n = len(self.chain_all)
self.chain_ann = chain_ann
self.param_labels = cosmic_params.ParamsProperty(param_names,params_dict=params_dict).labels
self.burnIn_step = burnIn_step
self.randn_num = randn_num
self.path = path
[docs] def plot_steps(self, layout_adjust=[0.3, 0.25], suptitle=''):
panel_model = BestFitsData(self.chain_all, self.chain_ann, param_labels=self.param_labels, burnIn_step=self.burnIn_step)
self.fig_steps = pl.MultiplePanels(panel_model).plot(layout_adjust=layout_adjust, ticks_size=10)
plt.suptitle(suptitle, fontsize=16)
return self.fig_steps
[docs] def plot_contours(self, bins=100, smooth=5, show_index=None, fill_contours=True, sigma=2, show_titles=True, line_width=2, lims=None):
if show_index is None:
chain_show = self.chain_ann
labels_show = self.param_labels
else:
index = [idx - 1 for idx in show_index]
chain_show = self.chain_ann[:, index]
labels_show = []
for idx in index:
labels_show.append(self.param_labels[idx])
if len(self.chain_ann.shape)==1:
self.fig_contours = plc.Plot_1d(chain_show).plot(bins=bins,labels=labels_show,smooth=smooth,
show_title=show_titles,line_width=line_width,
legend=False,legend_labels=['ANN'])
else:
self.fig_contours = plc.Contours(chain_show).plot(bins=bins,labels=labels_show,smooth=smooth,fill_contours=fill_contours,
show_titles=show_titles,line_width=line_width,layout_adjust=[0.0,0.0],
sigma=sigma,lims=lims,legend=False,legend_labels=['ANN'],best_values=None)
return self.fig_contours
@property
def randn_suffix(self):
return str(self.randn_num).split('.')[-1]
[docs] def save_steps(self):
pl.savefig(self.path+'/figures', 'steps_%s.pdf'%self.randn_suffix, self.fig_steps)
[docs] def save_contours(self):
pl.savefig(self.path+'/figures', 'contours_%s.pdf'%self.randn_suffix, self.fig_contours)
#%%
[docs]def pcc(x, y):
'''Pearson correlation coefficient
https://en.wikipedia.org/wiki/Pearson_correlation_coefficient
'''
data = np.c_[x, y].T
cov = np.cov(data)
rho = cov[0,1] / np.sqrt(cov[0,0]) / np.sqrt(cov[1,1])
return rho
[docs]class BestPredictedData(object):
def __init__(self, params_testSet, predParams_testSet, params_trainingSet=None,
predParams_trainingSet=None, param_labels='', show_reErr=True):
self.sim_params = params_testSet
self.pred_params = predParams_testSet
self.params_trainingSet = params_trainingSet
self.predParams_trainingSet = predParams_trainingSet
self.param_labels = param_labels
self.show_reErr = show_reErr
[docs] def panel_data(self, p_index):
data = {'labels' : [self.param_labels[p_index]+' (True)', self.param_labels[p_index]+' (Predicted)']}
data['sim_param'] = self.sim_params[:, p_index]
data['pred_param'] = self.pred_params[:, p_index]
data['pcc'] = pcc(self.sim_params[:, p_index], self.pred_params[:, p_index])
param_min_1, param_max_1 = self.sim_params[:, p_index].min(), self.sim_params[:, p_index].max()
param_min_2, param_max_2 = self.pred_params[:, p_index].min(), self.pred_params[:, p_index].max()
param_min, param_max = min([param_min_1, param_min_2]), max([param_max_1, param_max_2])
lims = [param_min, param_max, param_min, param_max]
data['lims'] = lims
pp = np.linspace(param_min, param_max, 100)
data['pp'] = pp
data['xx'] = (param_max-param_min)*0.06 + param_min #0.1, 0.06
data['yy'] = (param_max-param_min)*0.85 + param_min #0.8, 0.85
data['yy_pcc'] = (param_max-param_min)*0.72 + param_min #0.68, 0.72
return data
[docs] def panels_data(self):
datasets = []
re_err = (self.pred_params - self.sim_params) / self.sim_params
reErr_bestfit = su.Chains.bestFit(re_err, symmetry_error=False)#relative error of predicted parameters
for index in range(len(self.param_labels)):
data = self.panel_data(index)
data['reErr_bestfit'] = reErr_bestfit[index]
datasets.append(data)
return datasets
[docs] def panel(self, data):
plt.plot(data['sim_param'], data['pred_param'], '.')
plt.plot(data['pp'], data['pp'], 'r', lw=1.618)
if self.show_reErr:
plt.text(data['xx'], data['yy'], '$\delta: %.3f_{-%.3f}^{+%.3f}$'%(data['reErr_bestfit'][0],data['reErr_bestfit'][1],data['reErr_bestfit'][2]), fontsize=16)
plt.text(data['xx'], data['yy_pcc'], '$r: %.3f$'%(data['pcc']), fontsize=16)
# plt.legend(fontsize=12)
[docs]class PlotPrediction(object):
def __init__(self, params_testSet, predParams_testSet, param_names, params_trainingSet=None,
predParams_trainingSet=None, params_dict=None, show_reErr=True, randn_num='', path='ann'):
self.params_testSet = params_testSet
self.predParams_testSet = predParams_testSet
self.param_labels = cosmic_params.ParamsProperty(param_names,params_dict=params_dict).labels
self.params_trainingSet = params_trainingSet
self.predParams_trainingSet = predParams_trainingSet
self.show_reErr = show_reErr
self.randn_num = randn_num
self.path = path
[docs] def plot(self, layout_adjust=[0.3, 0.25], suptitle=''):
panel_model = BestPredictedData(self.params_testSet, self.predParams_testSet, param_labels=self.param_labels, show_reErr=self.show_reErr)
self.fig_pred = pl.MultiplePanels(panel_model).plot(layout_adjust=layout_adjust, ticks_size=10)
plt.suptitle(suptitle, fontsize=16)
return self.fig_pred
@property
def randn_suffix(self):
return str(self.randn_num).split('.')[-1]
[docs] def save_fig(self):
pl.savefig(self.path+'/figures', 'prediction_%s.pdf'%self.randn_suffix, self.fig_pred)