def __init__(self, simulation, emitter): self.simulation = simulation self.hmap = simulation.hmap self.emitter = emitter self.coords = np.array( [self.hmap.hmap[i].coords for i in range(self.hmap.n**2)]) self.colors = [ 'green' if self.hmap.hmap[i].state == 'terrain' else 'steelblue' for i in range(self.hmap.n**2) ] ax_x = Axis(label="x", scale=bqplot.LinearScale(min=0, max=2)) ax_y = Axis(label="y", scale=bqplot.LinearScale(min=0, max=2), orientation="vertical", side="left") self.grid_scat = plt.scatter(x=self.coords[:, 0], y=self.coords[:, 1], colors=self.colors, default_size=3, default_opacities=[.3], marker='rectangle') self.particles_scat = plt.scatter( x=[p.x for p in simulation.particles], y=[p.y for p in simulation.particles]) self.fig = plt.Figure(marks=[self.grid_scat, self.particles_scat], axes=[ax_x, ax_y], animation_duration=100, padding_x=.05, padding_y=.05) self.out = widgets.Output() def on_value_change(change): t = change['new'] if t == 1: self.simulation.reset() self.emitter.reset() self.hmap.reset() self.out.clear_output() self.particles_scat.x = [p.x for p in self.simulation.particles] self.particles_scat.y = [p.y for p in self.simulation.particles] self.simulation.update_particles() p = self.emitter.emit() if p: self.simulation.add_particle(p) self.slider = widgets.IntSlider(min=0, max=1000, step=1, continuous_update=True) self.play = widgets.Play(min=1, max=1000, interval=150) self.slider.observe(on_value_change, 'value') widgets.jslink((self.play, 'value'), (self.slider, 'value'))
def Interactive_Pareto_front(N,I_for,E_for,d_for,S0,Smax,Smin,env_min,c,solutions_optim_relea,results1_optim_relea,results2_optim_relea): members_num = np.shape(I_for)[0] population_size = np.shape(solutions_optim_relea)[0] sdpen = np.zeros([members_num,population_size]) sdpen_mean = np.zeros(population_size) sdpen_std = np.zeros(population_size) sd = np.zeros([members_num,population_size]) sd_mean = np.zeros(population_size) sd_std = np.zeros(population_size) for i in range(population_size): S_opt,env_opt,w_opt,r_opt = syst_sim(N,I_for+solutions_optim_relea[i],E_for,d_for,S0,Smax,env_min) sdpen[:,i] = np.sum(np.maximum(d_for-r_opt,np.zeros(np.shape(d_for)))**2,axis = 1) sdpen_mean[i] = np.mean(sdpen[:,i]) sdpen_std[i] = np.std(sdpen[:,i]) sd[:,i] = np.sum(np.maximum(d_for-r_opt,np.zeros(np.shape(d_for))),axis = 1) sd_mean[i] = np.mean(sd[:,i]) sd_std[i] = np.std(sd[:,i]) # Interactive Pareto front def update_operation(i): S,env,w,r = syst_sim(N,I_for+solutions_optim_relea[i],E_for,d_for,S0,Smax,env_min) fig_wd.title = 'Total supply deficit = '+str((sd_mean[i]).astype('int'))+' ± '+str((sd_std[i]).astype('int'))+' ML' fig_in.title = 'Natural + pumped inflows - Total pumped vol = {:.0f} ML'.format(results2_optim_relea[i]/c) return S,solutions_optim_relea[i],r,results1_optim_relea[i],results2_optim_relea[i],i def solution_selected(change): if pareto_front.selected == None: pareto_front.selected = [0] storage.y = update_operation(pareto_front.selected[0])[0] deficit.y = np.maximum(d_for-update_operation(pareto_front.selected[0])[2],np.zeros(np.shape(d_for))) pump_inflows.y = update_operation(pareto_front.selected[0])[1] tot_inflows.y = update_operation(pareto_front.selected[0])[1] + I_for pareto_front_ensemble.x = np.reshape([results2_optim_relea for i in range(0, members_num)],(members_num,population_size))[:,pareto_front.selected[0]] pareto_front_ensemble.y = sdpen[:,pareto_front.selected[0]] pareto_front_ensemble.unselected_style={'opacity': 0.1} pareto_front_ensemble.selected_style={'opacity': 0.1} pareto_front_ensemble.opacity = [0.1]*members_num x_sc_pf = LinearScale() y_sc_pf = LinearScale(min = 0,max = 4000) x_ax_pf = Axis(label='Total Pumping Cost [£]', scale=x_sc_pf) y_ax_pf = Axis(label='Total Squared Deficit [ML^2]', scale=y_sc_pf, orientation='vertical') pareto_front = plt.scatter(results2_optim_relea[:],results1_optim_relea[:],scales={'x': x_sc_pf, 'y': y_sc_pf},colors=['deepskyblue'], interactions={'hover':'tooltip','click': 'select'}) pareto_front.unselected_style={'opacity': 0.8} pareto_front.selected_style={'fill': 'red', 'stroke': 'yellow', 'width': '1125px', 'height': '125px'} if pareto_front.selected == []: pareto_front.selected = [0] pareto_front_ensemble = plt.Scatter(x=np.reshape([results2_optim_relea for i in range(0, members_num)],(members_num,population_size))[:,pareto_front.selected[0]], y=sdpen[:,pareto_front.selected[0]],scales={'x': x_sc_pf, 'y': y_sc_pf}, colors=['red'], interactions={'hover':'tooltip','click': 'select'}) pareto_front_ensemble.unselected_style={'opacity': 0.1} pareto_front_ensemble.selected_style={'opacity': 0.1} pareto_front_ensemble.opacity = [0.1]*members_num fig_pf = plt.Figure(marks=[pareto_front,pareto_front_ensemble],title = 'Pareto front', axes=[x_ax_pf, y_ax_pf],layout={'width': '500px', 'height': '500px'}, animation_duration=500) pareto_front.observe(solution_selected,'selected') S,env,w,r = syst_sim(N,I_for+solutions_optim_relea[pareto_front.selected[0]],E_for,d_for,S0,Smax,env_min) x_sc_in = OrdinalScale(min=1,max=N) y_sc_in = LinearScale(min=0,max=100) x_ax_in = Axis(label='week', scale=x_sc_in) y_ax_in = Axis(label='ML/week', scale=y_sc_in, orientation='vertical') x_sc_st = LinearScale(min=0,max=N) y_sc_st = LinearScale(min=0,max=160) x_ax_st = Axis(label='week', scale=x_sc_st)#,tick_values=[0.5,1.5,2.5,3.5]) y_ax_st = Axis(label='ML', scale=y_sc_st, orientation='vertical') x_sc_wd = LinearScale(min=0.5,max=N+0.5) y_sc_wd = LinearScale(min=0,max=100); x_ax_wd = Axis(label='week', scale=x_sc_wd,tick_values=[1,2,3,4,5,6,7,8]) y_ax_wd = Axis(label='ML/week', scale=y_sc_wd, orientation='vertical') pump_inflows = plt.Lines(x=np.arange(1,N+1), y=solutions_optim_relea[pareto_front.selected[0]], scales={'x': x_sc_in, 'y': y_sc_in}, colors=['orange'], opacities = [1], stroke_width = 1, marker = 'circle', marker_size = 10, labels = ['pump (Qreg_inf)'], fill = 'bottom', fill_opacities = [1], fill_colors = ['orange']*members_num*N) tot_inflows = plt.Lines(x = np.arange(1,N+1), y = solutions_optim_relea[pareto_front.selected[0]]+I_for, scales={'x': x_sc_wd, 'y': y_sc_wd}, colors=['blue'], opacities = [1]*members_num, stroke_width = 0.5, marker = 'circle', marker_size = 10, labels = ['nat (I) + pump (Qreg_inf)'], fill = 'bottom', fill_opacities = [1/members_num]*members_num*N, fill_colors = ['blue']*members_num*N) fig_in = plt.Figure(marks = [tot_inflows,pump_inflows],axes=[x_ax_in, y_ax_in],layout={'max_width': '480px', 'max_height': '250px'}, scales={'x': x_sc_in, 'y': y_sc_in}, animation_duration=1000,legend_location = 'bottom-right') storage = plt.plot(x=np.arange(0,N+1),y=S,scales={'x': x_sc_st, 'y': y_sc_st}, colors=['blue'], stroke_width = 0.1, fill = 'bottom', fill_opacities = [0.1]*members_num) max_storage = plt.plot(x=np.arange(0,N+1), y=[Smax]*(N+1), colors=['red'], scales={'x': x_sc_st, 'y': y_sc_st}) max_storage_label = plt.label(text = ['Max storage'], x=[0], y=[Smax+10], colors=['red']) fig_st = plt.Figure(marks = [storage,max_storage,max_storage_label], title = 'Reservoir storage volume', axes=[x_ax_st, y_ax_st], layout={'width': '1000px', 'height': '350px'}, animation_duration=1000, scales={'x': x_sc_st, 'y': y_sc_st}) deficit = plt.Lines(x = np.arange(1,N+1), y = np.maximum(d_for-r,np.zeros(np.shape(r))), scales={'x': x_sc_wd, 'y': y_sc_wd}, colors=['red'], stroke_width = 1, opacities = [1]*members_num, marker = 'circle', marker_size = 10, labels = ['max(0,d-Qreg_rel)'], fill = 'bottom', fill_opacities = [1/members_num]*members_num, fill_colors = ['red']*members_num) fig_wd = plt.Figure(marks = [deficit],axes=[x_ax_wd, y_ax_wd], layout={'max_width': '480px', 'max_height': '250px'}, animation_duration=1000, legend_location = 'bottom-right') storage.y = update_operation(pareto_front.selected[0])[0] deficit.y = np.maximum(d_for-update_operation(pareto_front.selected[0])[2],np.zeros(np.shape(d_for))) pump_inflows.y = update_operation(pareto_front.selected[0])[1] tot_inflows.y = update_operation(pareto_front.selected[0])[1] + I_for storage.observe(solution_selected, ['x', 'y']) deficit.observe(solution_selected, ['x', 'y']) pump_inflows.observe(solution_selected, ['x', 'y']) tot_inflows.observe(solution_selected, ['x', 'y']) return fig_pf,fig_wd,fig_st,fig_in,pareto_front
def Interactive_Pareto_front_act(N,I_act,E_act,d_act,S0,Smax,Smin,env_min,c,solutions_optim_relea_2,results1_optim_relea_2,results2_optim_relea_2,sel_policy): population_size = np.shape(solutions_optim_relea_2)[0] sdpen_act_4 = np.zeros(population_size); pcost_act_4 = np.zeros(population_size) for i in range(population_size): pinfl_policy_4 = np.array(solutions_optim_relea_2[i]) S_act_4,env_act_4,w_act_4,r_act_4 = syst_sim(N,I_act+pinfl_policy_4,E_act,d_act,S0,Smax,env_min) sdpen_act_4[i] = (np.sum((np.maximum(d_act-r_act_4,[0]*N))**2)).astype('int') pcost_act_4[i] = (np.sum(np.array(pinfl_policy_4)*c)).astype('int') def update_operation_act_4(i): u = solutions_optim_relea_2[i] S,env,w,r = syst_sim(N,I_act+u,E_act,d_act,S0,Smax,env_min) fig_4b.title = 'Total supply deficit = '+str((np.sum((np.maximum(d_act-r,[0]*N)))).astype('int'))+' ML' fig_4d.title = 'Natural + pumped inflows - Total pumped vol = '+str((np.sum(np.array(u))).astype('int'))+' ML' return S,u,r,i def solution_selected_act_4(change): if pareto_front_act_4.selected == None: pareto_front_act_4.selected = [0] deficit_4.y = np.maximum(d_act-update_operation_act_4(pareto_front_act_4.selected[0])[2], [0]*N) storage_4.y = update_operation_act_4(pareto_front_act_4.selected[0])[0] pump_inflows_4.y = [update_operation_act_4(pareto_front_act_4.selected[0])[1]] tot_inflows_4.y = [update_operation_act_4(pareto_front_act_4.selected[0])[1]+I_act[0]] def on_hover_4pf(self, target): hover_elem_id = list(target.values())[1]['index'] def on_element_click_4pf(self, target): click_elem_id = list(target.values())[1]['index'] colors = ['deepskyblue']*population_size colors[click_elem_id] = 'red' pareto_front_4.colors = colors x_sc_2pf = LinearScale() y_sc_2pf = LinearScale() x_ax_2pf = Axis(label='Total Pumping Cost [£]', scale=x_sc_2pf) y_ax_2pf = Axis(label='Total Squared Deficit [ML^2]', scale=y_sc_2pf, orientation='vertical') pareto_front_4 = plt.scatter(results2_optim_relea_2[:], results1_optim_relea_2[:], scales={'x': x_sc_2pf, 'y': y_sc_2pf}, colors=['deepskyblue'], opacity = [0.11]*population_size, interactions={'hover':'tooltip'}) pareto_front_4.tooltip = None pareto_front_act_4 = plt.scatter(pcost_act_4[:],sdpen_act_4[:],scales={'x': x_sc_2pf, 'y': y_sc_2pf}, colors=['green'], interactions={'hover':'tooltip'}) pareto_front_act_4.unselected_style = {'opacity': 0} pareto_front_act_4.selected_style = {'fill': 'black', 'stroke': 'black', 'width': '1125px', 'height': '125px'} pareto_front_4.selected_style = {'fill': 'red', 'stroke': 'red', 'width': '1125px', 'height': '125px'} pareto_front_act_4.tooltip = None fig_4pf = plt.Figure(marks = [pareto_front_4,pareto_front_act_4 ],title = 'Pareto front', axes=[x_ax_2pf, y_ax_2pf], layout={'width': '500px', 'height': '500px'}, animation_duration=1000) if pareto_front_act_4.selected == []: pareto_front_4.selected = [sel_policy] pareto_front_act_4.selected = [sel_policy] pareto_front_act_4.observe(solution_selected_act_4,'selected') pareto_front_act_4.on_hover(on_hover_4pf) pareto_front_4.on_hover(on_hover_4pf) x_sc_2b = OrdinalScale(min=1, max=N) y_sc_2b = LinearScale(min=0, max=100) x_ax_2b = Axis(label='week', scale=x_sc_2b) y_ax_2b = Axis(label='ML/week', scale=y_sc_2b, orientation='vertical') deficit_4 = plt.Lines(x=np.arange(1,N+1), y=np.maximum(d_act-r_act_4,[0]*N), colors=['red'], opacities = [1], stroke_width = 0.5, marker = 'circle', marker_size = 15, labels = ['max(0,d-Qreg_rel)'], fill = 'bottom', fill_opacities = [0.5], fill_colors = ['red'], display_legend = False, scales={'x': x_sc_2b, 'y': y_sc_2b}) fig_4b = plt.Figure(marks = [deficit_4], axes=[x_ax_2b, y_ax_2b], layout={'width': '480px', 'height': '250px'}, scales={'x': x_sc_2b, 'y': y_sc_2b}, animation_duration=1000, legend_location = 'bottom-right', legend_style = {'fill': 'white', 'opacity': 0.5}) x_sc_2c = LinearScale(min=0, max=N) y_sc_2c = LinearScale(min=0, max=160) x_ax_2c = Axis(label='week', scale=x_sc_2c) y_ax_2c = Axis(label='ML', scale=y_sc_2c, orientation='vertical') max_storage_2 = plt.plot(x=np.arange(0,N+1), y=[Smax]*(N+1), colors=['red'], scales={'x': x_sc_2c, 'y': y_sc_2c}) max_storage_label_2 = plt.label(text = ['Max storage'], x=[0], y=[Smax+10], colors=['red']) storage_4 = plt.Lines(x=np.arange(0,N+1), y=S_act_4, colors=['blue'], scales={'x': x_sc_2c, 'y': y_sc_2c}, fill = 'bottom',fill_opacities = [0.8], fill_colors = ['blue']) fig_4c = plt.Figure(marks = [storage_4,max_storage_2,max_storage_label_2], title = 'Reservoir storage (s)', axes=[x_ax_2c, y_ax_2c], layout={'width': '1000px', 'height': '350px'}, animation_duration=1000, scales={'x': x_sc_2c, 'y': y_sc_2c}) x_sc_2d = OrdinalScale(min=1, max=N) y_sc_2d = LinearScale(min=0, max=100) x_ax_2d = Axis(label='week', scale=x_sc_2d) y_ax_2d = Axis(label='ML/week', scale=y_sc_2d, orientation='vertical') pump_inflows_4 = plt.Lines(x=np.arange(1,N+1), y=[pinfl_policy_4], colors=['orange'], opacities = [1], stroke_width = 0.5, marker = 'circle', marker_size = 15, fill = 'bottom', fill_opacities = [1], fill_colors = ['orange'], labels = ['pump (Qreg_inf)'], display_legend = True, scales={'x': x_sc_2d, 'y': y_sc_2d}) tot_inflows_4 = plt.Lines(x=np.arange(1,N+1), y=[pinfl_policy_4+I_act[0]], colors=['blue'], opacities = [1], stroke_width = 1, marker = 'circle', marker_size = 15, fill = 'bottom', fill_opacities = [0.5], fill_colors = ['blue'], labels = ['nat (I) + pump (Qreg_inf)'], display_legend = True, scales={'x': x_sc_2d, 'y': y_sc_2d}) fig_4d = plt.Figure(marks = [tot_inflows_4,pump_inflows_4], title = 'Natural + pumped inflows', axes=[x_ax_2d, y_ax_2d], layout={'width': '480px', 'height': '250px'}, scales={'x': x_sc_2d, 'y': y_sc_2d}, animation_duration=1000, legend_location = 'top', legend_style = {'fill': 'white', 'opacity': 0.5}) deficit_4.y = np.maximum(d_act-update_operation_act_4(sel_policy)[2],[0]*N) storage_4.y = update_operation_act_4(sel_policy)[0] pump_inflows_4.y = [update_operation_act_4(sel_policy)[1]] tot_inflows_4.y = [update_operation_act_4(sel_policy)[1]+I_act[0]] deficit_4.observe(solution_selected_act_4, ['x', 'y']) storage_4.observe(solution_selected_act_4, ['x', 'y']) pump_inflows_4.observe(solution_selected_act_4, ['x', 'y']) tot_inflows_4.observe(solution_selected_act_4, ['x', 'y']) return fig_4b,fig_4c,fig_4d,fig_4pf
def Interactive_Pareto_front_det(N,I_sel,E,d_sel,S0,Smax,Smin,env_min,c,solutions_optim_relea_2,results1_optim_relea_2,results2_optim_relea_2): def update_operation_2(i): u = solutions_optim_relea_2[i] S,env,w,r = syst_sim(N,I_sel+u,E,d_sel,S0,Smax,env_min) fig_2b.title = 'Total supply deficit = '+str((np.sum((np.maximum(d_sel-r,[0]*N)))).astype('int'))+' ML' fig_2d.title = 'Natural + pumped inflows - Total pumped vol = '+str((np.sum(np.array(u))).astype('int'))+' ML' return S,u,r,i def solution_selected_2(change): if pareto_front_2.selected == None: pareto_front_2.selected = [0] deficit_2.y = np.maximum(d_sel-update_operation_2(pareto_front_2.selected[0])[2],[0]*N) storage_2.y = update_operation_2(pareto_front_2.selected[0])[0] pump_inflows_2.y = [update_operation_2(pareto_front_2.selected[0])[1]] tot_inflows_2.y = [update_operation_2(pareto_front_2.selected[0])[1]+I_sel[0]] x_sc_2pf = LinearScale();y_sc_2pf = LinearScale() x_ax_2pf = Axis(label='Total Pumping Cost [£]', scale=x_sc_2pf) y_ax_2pf = Axis(label='Total Squared Deficit [ML^2]', scale=y_sc_2pf, orientation='vertical') pareto_front_2 = plt.scatter(results2_optim_relea_2[:],results1_optim_relea_2[:],scales={'x': x_sc_2pf, 'y': y_sc_2pf}, colors=['deepskyblue'], interactions={'hover':'tooltip','click': 'select'}) pareto_front_2.unselected_style = {'opacity': 0.4} pareto_front_2.selected_style = {'fill': 'red', 'stroke': 'yellow', 'width': '1125px', 'height': '125px'} def_tt = Tooltip(fields=['x', 'y','index'],labels=['Pumping cost','Squared deficit', 'sol index'], formats=['.1f', '.1f', '.0f']) pareto_front_2.tooltip = def_tt fig_2pf = plt.Figure(marks = [pareto_front_2],title = 'Pareto front', axes=[x_ax_2pf, y_ax_2pf], layout={'width': '500px', 'height': '500px'}, animation_duration=1000) if pareto_front_2.selected == []: pareto_front_2.selected = [0] pareto_front_2.observe(solution_selected_2,'selected') S,env,w,r = syst_sim(N,I_sel+solutions_optim_relea_2[pareto_front_2.selected[0]],E,d_sel,S0,Smax,env_min) x_sc_2b = OrdinalScale(min=1,max=N);y_sc_2b = LinearScale(min=0,max=100) x_ax_2b = Axis(label='week', scale=x_sc_2b) y_ax_2b = Axis(label='ML/week', scale=y_sc_2b, orientation='vertical') deficit_2 = plt.Lines(x=np.arange(1,N+1), y=np.maximum(d_sel-r,[0]*N), colors=['red'], opacities = [1], stroke_width = 0.5, marker = 'circle', marker_size = 15, labels = ['max(0,d-Qreg_rel)'], fill = 'bottom', fill_opacities = [0.5], fill_colors = ['red'], display_legend = False, scales={'x': x_sc_2b, 'y': y_sc_2b}) fig_2b = plt.Figure(marks = [deficit_2], axes=[x_ax_2b, y_ax_2b], layout={'width': '480px', 'height': '250px'}, scales={'x': x_sc_2b, 'y': y_sc_2b}, animation_duration=1000, legend_location = 'bottom-right', legend_style = {'fill': 'white', 'opacity': 0.5}) x_sc_2c = LinearScale(min=0,max=N) y_sc_2c = LinearScale(min=0,max=160) x_ax_2c = Axis(label='week', scale=x_sc_2c) y_ax_2c = Axis(label='ML', scale=y_sc_2c, orientation='vertical') storage_2 = plt.Lines(x=np.arange(0,N+1), y=S,colors=['blue'], scales={'x': x_sc_2c, 'y': y_sc_2c}, fill = 'bottom', fill_opacities = [0.8], fill_colors = ['blue']) max_storage_2 = plt.plot(x=np.arange(0,N+1), y=[Smax]*(N+1), colors=['red'], scales={'x': x_sc_2c, 'y': y_sc_2c}) max_storage_label_2 = plt.label(text = ['Max storage'], x=[0], y=[Smax+10], colors=['red']) fig_2c = plt.Figure(marks = [storage_2,max_storage_2,max_storage_label_2], title = 'Reservoir storage (s)', axes=[x_ax_2c, y_ax_2c], layout={'width': '1000px', 'height': '350px'}, animation_duration=1000, scales={'x': x_sc_2c, 'y': y_sc_2c}) x_sc_2d = OrdinalScale(min=1, max=N) y_sc_2d = LinearScale(min=0, max=100) x_ax_2d = Axis(label='week', scale=x_sc_2d) y_ax_2d = Axis(label='ML/week', scale=y_sc_2d, orientation='vertical') # Stacked bars pump_inflows_2 = plt.Lines(x=np.arange(1,N+1), y=(solutions_optim_relea_2[pareto_front_2.selected[0]]), colors=['orange'], opacities = [1], stroke_width = 0.5, marker = 'circle', marker_size = 15, fill = 'bottom', fill_opacities = [1], fill_colors = ['orange'], labels = ['pump (Qreg_inf)'], display_legend = True, scales={'x': x_sc_2d, 'y': y_sc_2d}) tot_inflows_2 = plt.Lines(x=np.arange(1,N+1), y=(solutions_optim_relea_2[pareto_front_2.selected[0]]+I_sel[0]), colors=['blue'], opacities = [1], stroke_width = 1, marker = 'circle', marker_size = 15, fill = 'bottom', fill_opacities = [0.5], fill_colors = ['blue'], labels = ['nat (I) + pump (Qreg_inf)'], display_legend = True, scales={'x': x_sc_2d, 'y': y_sc_2d}) fig_2d = plt.Figure(marks = [tot_inflows_2,pump_inflows_2], title = 'Natural + pumped inflows', axes=[x_ax_2d, y_ax_2d], layout={'width': '480px', 'height': '250px'}, scales={'x': x_sc_2d, 'y': y_sc_2d}, animation_duration=1000, legend_location = 'top', legend_style = {'fill': 'white', 'opacity': 0.5}) deficit_2.y = np.maximum(d_sel-update_operation_2(pareto_front_2.selected[0])[2],[0]*N) storage_2.y = update_operation_2(pareto_front_2.selected[0])[0] pump_inflows_2.y = [update_operation_2(pareto_front_2.selected[0])[1]] tot_inflows_2.y = [update_operation_2(pareto_front_2.selected[0])[1]+I_sel[0]] deficit_2.observe(solution_selected_2, ['x', 'y']) storage_2.observe(solution_selected_2, ['x', 'y']) pump_inflows_2.observe(solution_selected_2, ['x', 'y']) tot_inflows_2.observe(solution_selected_2, ['x', 'y']) return fig_2pf,fig_2b,fig_2c,fig_2d,pareto_front_2
angle_loc = exact_theta(init_h,init_d)/2 xc,yc = par_circ(r=arc_loc, theta0=2*np.pi-angle_loc, theta1=2*np.pi+angle_loc) angle_ex = bq.Lines(x=xc, y=yc, scales={'x': sc_x, 'y': sc_y}, colors=['white']) angle_label = bq.Label(x=[2], y=[0], scales={'x': sc_x, 'y': sc_y}, text=[r'$$\theta$$'], default_size=15, font_weight='bolder', colors=['white'], update_on_move=False) # Update the the plot/display h_slider.observe(update, names=['value']) d_slider.observe(update, names=['value']) # Creates the figure. The background color is set to black so that it looks like 'space.' Also, # removes the default y padding. fig = bq.Figure(title='Small Angle Approximation', marks=[Object,D1,D2,angle_ex], axes=[ax_x, ax_y], padding_x=0, padding_y=0, animation=100, background_style={'fill' : 'black'}) # Display to the screen # Set up the figure fig_width = 750 fig.layout.width = '{:.0f}px'.format(fig_width) fig.layout.height = '{:.0f}px'.format(fig_width/2) # Set up the bottom part containing the controls and display of equations h_box = widgets.VBox([h_label, h_slider]) d_box = widgets.VBox([d_label, d_slider]) slide_box = widgets.HBox([h_box, d_box]) h_box.layout.width = '{:.0f}px'.format(fig_width/2) d_box.layout.width = '{:.0f}px'.format(fig_width/2)
def Interactive_release_single(simtime,I,E,d,S0,Smax,env_min, demand_plot): def syst_sim(simtime,I,E,d,S0,Smax,env_min,Qreg): # Declare output variables S = [0]*(simtime+1) # reservoir storage in ML spill = [0]*(simtime) # spillage in ML env = [env_min]*(simtime) # environmental compensation flow S[0] = S0 # initial storage for t in range(simtime): # Loop for each time-step (week) # If at week t the inflow (I) is lower than the minimum environmental compensation (env_min), # then the environmental compensation (env) = inflow (I) if env_min >= I[t] : env[t] = I[t] # If the minimum environmental compensation is higher than the water resource available (S + I - E) # then the environmental compensation is equal to the higher value between 0 and the resource available if env_min >= S[t] + I[t] - E[t]: env[t] = max(0,S[t] + I[t] - E[t]) # S[t] = Smin then env[t] = I[t] and S[t+1] < Smin # If the demand is higher than the water resource available (S + I - E - env) # then the release for water supply is equal to the higher value between 0 and the resource available if d[t] >= S[t] + I[t] - E[t] - env[t]: Qreg[t] = min(Qreg[t],max(0,S[t] + I[t] - E[t] - env[t])) # The spillage is equal to the higher value between 0 and the resource available exceeding the reservoir capacity spill[t] = max(0,S[t] + I[t] - Qreg[t] - env[t] - E[t] - Smax) # The final storage (initial storage in the next step) is equal to the storage + inflow - outflows S[t+1] = S[t] + I[t] - Qreg[t] - env[t]- E[t] - spill[t] return S,env,spill,Qreg # Interactive operating rule definition def update_operation_2(Qreg): S,env,spill,Qreg1 = syst_sim(simtime,I,E,d,S0,Smax,env_min,Qreg) sdpen = (np.sum((np.maximum(d-Qreg1,[0]*simtime))**2)).astype('int') fig_2b.title = 'Supply vs Demand - Total squared deficit = '+str(sdpen)+' ML^2' return S,Qreg1 def policy_changed_2a(change): y_vals_2a = update_operation_2([release1.value,release2.value,release3.value,release4.value, release5.value,release6.value,release7.value,release8.value])[0] storage_2.y = y_vals_2a def policy_changed_2b(change): y_vals_2b = update_operation_2([release1.value,release2.value,release3.value,release4.value, release5.value,release6.value,release7.value,release8.value])[1] releases_2.y = y_vals_2b release1 = widgets.FloatSlider(min = 0, max = 40, step=1, value = 0, description = 'Week 1',orientation='vertical',layout={'width': '100px'}) release1.observe(policy_changed_2a,'value') release1.observe(policy_changed_2b,'value') release2 = widgets.FloatSlider(min = 0, max = 40, step=1, value = 0, description = 'Week 2',orientation='vertical',layout={'width': '100px'}) release2.observe(policy_changed_2a,'value') release2.observe(policy_changed_2b,'value') release3 = widgets.FloatSlider(min = 0, max = 40, step=1, value = 0, description = 'Week 3',orientation='vertical',layout={'width': '100px'}) release3.observe(policy_changed_2a,'value') release3.observe(policy_changed_2b,'value') release4 = widgets.FloatSlider(min = 0, max = 40, step=1, value = 0, description = 'Week 4',orientation='vertical',layout={'width': '100px'}) release4.observe(policy_changed_2a,'value') release4.observe(policy_changed_2b,'value') release5 = widgets.FloatSlider(min = 0, max = 40, step=1, value = 0, description = 'Week 5',orientation='vertical',layout={'width': '100px'}) release5.observe(policy_changed_2a,'value') release5.observe(policy_changed_2b,'value') release6 = widgets.FloatSlider(min = 0, max = 40, step=1, value = 0, description = 'Week 6',orientation='vertical',layout={'width': '100px'}) release6.observe(policy_changed_2a,'value') release6.observe(policy_changed_2b,'value') release7 = widgets.FloatSlider(min = 0, max = 40, step=1, value = 0, description = 'Week 7',orientation='vertical',layout={'width': '100px'}) release7.observe(policy_changed_2a,'value') release7.observe(policy_changed_2b,'value') release8 = widgets.FloatSlider(min = 0, max = 40, step=1, value = 0, description = 'Week 8',orientation='vertical',layout={'width': '100px'}) release8.observe(policy_changed_2a,'value') release8.observe(policy_changed_2b,'value') u=[release1.value,release2.value,release3.value,release4.value,release5.value,release6.value,release7.value,release8.value] S,env,w,u1 = syst_sim(simtime,I,E,d,S0,Smax,env_min,np.array([0]*simtime)) sdpen = np.sum((np.maximum(d-u1,[0]*simtime))**2).astype('int') x_sc_1 = LinearScale();y_sc_1 = LinearScale(min=0,max=35);x_ax_1 = Axis(label='week', scale=x_sc_1);y_ax_1 = Axis(label='ML/week', scale=y_sc_1, orientation='vertical') x_sc_2a = LinearScale(min=0,max=simtime);y_sc_2a = LinearScale(min=0,max=200);x_ax_2a = Axis(label='week', scale=x_sc_2a,tick_values=np.arange(8)+0.5);y_ax_2a = Axis(label='ML', scale=y_sc_2a, orientation='vertical') storage_2 = Lines(x=np.arange(0,simtime+1),y=S,colors=['blue'],scales={'x': x_sc_2a, 'y': y_sc_2a},fill = 'bottom',fill_opacities = [0.8],fill_colors = ['blue']) max_storage_2 = plt.plot(x=np.arange(0,simtime+1),y=[Smax]*(simtime+1),colors=['red'],scales={'x': x_sc_2a, 'y': y_sc_2a}) max_storage_label_2 = plt.label(text = ['Max storage'], x=[0],y=[Smax+15],colors=['red']) fig_2a = plt.Figure(marks = [storage_2,max_storage_2,max_storage_label_2],title = 'Reservoir storage volume', axes=[x_ax_2a, y_ax_2a],layout={'width': '950px', 'height': '300px'}, animation_duration=1000,scales={'x': x_sc_2a, 'y': y_sc_2a}) releases_2 = plt.bar(np.arange(1,simtime+1),u1,colors=['green'],opacities = [0.7]*simtime, labels = ['release'], display_legend = True, stroke_width = 1,scales={'x': x_sc_1, 'y': y_sc_1}) fig_2b = plt.Figure(marks = [demand_plot,releases_2],axes=[x_ax_1, y_ax_1], layout={'min_width': '950px', 'max_height': '300px'}, animation_duration=0,legend_location = 'top-left',legend_style = {'fill': 'white', 'opacity': 0.5}) storage_2.y = update_operation_2(u)[0] releases_2.y = update_operation_2(u)[1] storage_2.observe(policy_changed_2a, ['x', 'y']) releases_2.observe(policy_changed_2b, ['x', 'y']) return fig_2a,fig_2b,release1,release2,release3,release4,release5,release6,release7,release8
def Interactive_Pareto_front(simtime,I,E,d,S0,Smax,ms,env_min, demand_plot,solutions_optim_relea,results1_optim_relea,results2_optim_relea): def syst_sim(simtime,I,E,d,S0,Smax,env_min,Qreg): # Declare output variables S = [0]*(simtime+1) # reservoir storage in ML spill = [0]*(simtime) # spillage in ML env = [env_min]*(simtime) # environmental compensation flow S[0] = S0 # initial storage for t in range(simtime): # Loop for each time-step (week) # If at week t the inflow (I) is lower than the minimum environmental compensation (env_min), # then the environmental compensation (env) = inflow (I) if env_min >= I[t] : env[t] = I[t] # If the minimum environmental compensation is higher than the water resource available (S + I - E) # then the environmental compensation is equal to the higher value between 0 and the resource available if env_min >= S[t] + I[t] - E[t]: env[t] = max(0,S[t] + I[t] - E[t]) # S[t] = Smin then env[t] = I[t] and S[t+1] < Smin # If the demand is higher than the water resource available (S + I - E - env) # then the release for water supply is equal to the higher value between 0 and the resource available if d[t] >= S[t] + I[t] - E[t] - env[t]: Qreg[t] = min(Qreg[t],max(0,S[t] + I[t] - E[t] - env[t])) # The spillage is equal to the higher value between 0 and the resource available exceeding the reservoir capacity spill[t] = max(0,S[t] + I[t] - Qreg[t] - env[t] - E[t] - Smax) # The final storage (initial storage in the next step) is equal to the storage + inflow - outflows S[t+1] = S[t] + I[t] - Qreg[t] - env[t]- E[t] - spill[t] return S,env,spill,Qreg def update_operation_4(i): Qreg = solutions_optim_relea[i] S,env,spill,Qreg1 = syst_sim(simtime,I,E,d,S0,Smax,env_min,Qreg) lspen = np.sum((np.maximum(ms-S,[0]*(simtime+1)))).astype('int') fig_4a.title = 'Reservoir storage - Minimum storage violation = '+str(lspen)+' ML' sdpen = (np.sum((np.maximum(d-Qreg1,[0]*simtime))**2)).astype('int') fig_4b.title = 'Supply vs Demand - Total squared deficit = '+str(sdpen)+' ML^2' return S,env,spill,Qreg1 def solution_selected(change): if pareto_front.selected == None: pareto_front.selected = [0] y_vals_4a = update_operation_4(pareto_front.selected[0])[0] storage_4.y = y_vals_4a y_vals_4b = update_operation_4(pareto_front.selected[0])[3] releases_4.y = y_vals_4b x_sc_pf = LinearScale();y_sc_pf = LinearScale() x_ax_pf = Axis(label='Total squared deficit [ML^2]', scale=x_sc_pf) y_ax_pf = Axis(label='Minimum storage violation [ML]', scale=y_sc_pf, orientation='vertical') pareto_front = plt.scatter(results1_optim_relea[:],results2_optim_relea[:],scales={'x': x_sc_pf, 'y': y_sc_pf}, colors=['deepskyblue'], interactions={'hover':'tooltip','click': 'select'}) pareto_front.unselected_style={'opacity': 0.4} pareto_front.selected_style={'fill': 'red', 'stroke': 'yellow', 'width': '1125px', 'height': '125px'} def_tt = Tooltip(fields=['x', 'y'],labels=['Water deficit', 'Min storage'], formats=['.1f', '.1f']) pareto_front.tooltip=def_tt fig_pf = plt.Figure(marks = [pareto_front],title = 'Interactive Pareto front', axes=[x_ax_pf, y_ax_pf], layout={'width': '500px', 'height': '500px'}, animation_duration=1000) if pareto_front.selected == []: pareto_front.selected = [0] pareto_front.observe(solution_selected,'selected') S,env,w,u1 = syst_sim(simtime,I,E,d,S0,Smax,env_min,solutions_optim_relea[pareto_front.selected[0]]) x_sc_1 = LinearScale();y_sc_1 = LinearScale(min=0,max=35);x_ax_1 = Axis(label='week', scale=x_sc_1);y_ax_1 = Axis(label='ML/week', scale=y_sc_1, orientation='vertical') x_sc_2a = LinearScale(min=0,max=simtime);y_sc_2a = LinearScale(min=0,max=200);x_ax_2a = Axis(label='week', scale=x_sc_2a,tick_values=np.arange(8)+0.5);y_ax_2a = Axis(label='ML', scale=y_sc_2a, orientation='vertical') max_storage_2 = plt.plot(x=np.arange(0,simtime+1),y=[Smax]*(simtime+1),colors=['red'],scales={'x': x_sc_2a, 'y': y_sc_2a}) max_storage_label_2 = plt.label(text = ['Max storage'], x=[0],y=[Smax+15],colors=['red']) min_storage_3 = plt.plot(np.arange(0,simtime+1),ms,scales={'x': x_sc_2a, 'y': y_sc_2a},colors=['red'],opacities = [1],line_style = 'dashed', fill = 'bottom',fill_opacities = [0.4],fill_colors = ['red'], stroke_width = 1) min_storage_label_3 = plt.label(text = ['Min storage'], x=[0],y=[ms[0]-10],colors=['red']) storage_4 = Lines(x=range(simtime+1),y=S,scales={'x': x_sc_2a, 'y': y_sc_2a}, fill = 'bottom',fill_opacities = [0.7]*simtime, fill_colors = ['blue']) fig_4a = plt.Figure(marks = [min_storage_3,storage_4,max_storage_2,max_storage_label_2,min_storage_label_3], axes=[x_ax_2a, y_ax_2a],layout={'width': '480px', 'height': '250px'},animation_duration=1000) releases_4 = plt.bar(np.arange(1,simtime+1),u1,colors=['green'],opacities = [0.7]*simtime,scales={'x': x_sc_1, 'y': y_sc_1}, labels = ['release'], display_legend = True, stroke_width = 1) fig_4b = plt.Figure(marks = [demand_plot, releases_4], axes=[x_ax_1, y_ax_1],layout={'width': '480px', 'height': '250px'}, animation_duration=1000,legend_location = 'top-left',legend_style = {'fill': 'white', 'opacity': 0.5}) storage_4.y = update_operation_4(pareto_front.selected[0])[0] releases_4.y = update_operation_4(pareto_front.selected[0])[3] storage_4.observe(solution_selected, ['x', 'y']) releases_4.observe(solution_selected, ['x', 'y']) return fig_4a,fig_4b,fig_pf
def Interactive_policy_auto(N, I_hist, e_hist, s_0, s_min, s_max, u_0, u_1, u_mean, u_max, env_min, d_hist, rc, results1_optim,results2_optim,sol_optim): # Function to update the release policy when clicking on the points of the Pareto front def update_operating_policy_2(i): u_ref,s_ref_1,s_ref_2 = sol_optim[i] x0 = [0, u_0] x1 = [s_ref_1, u_ref] x2 = [s_ref_2, u_ref] x3 = [1, u_1] param = [x0, x1, x2, x3, u_mean] u_frac = four_points_policy(param)/u_mean Qreg = {'releases' : {'file_name' : 'Reservoir_operating_policy.Operating_policy_functions', 'function' : 'four_points_policy', 'param': param}, 'inflows' : [], 'rel_inf' : []} Qenv, Qspill, u, I_reg, s, E = Res_sys_sim(I_hist, e_hist, s_0, s_min, s_max, env_min, d_hist, Qreg) MSV = (np.sum((np.maximum(rc-s,[0]*(N+1))))).astype('int') fig_2c.title = 'Reservoir storage volume - MSV = '+str(MSV)+' ML' TSD = (np.sum((np.maximum(d_hist-u,[0]*N))**2)).astype('int') fig_2b.title = 'Supply vs Demand - Total squared deficit = '+str(TSD)+' ML^2' return u_frac, Qenv, Qspill, u, I_reg, s # Function to update the figures when clicking on the points of the Pareto front def update_figure_2(change): policy_function.y = update_operating_policy_2(pareto_front.selected[0])[0] releases.y = update_operating_policy_2(pareto_front.selected[0])[3] storage.y = update_operating_policy_2(pareto_front.selected[0])[5] # Fig_pf: Pareto front x_sc_pf = LinearScale();y_sc_pf = LinearScale() x_ax_pf = Axis(label='Total squared deficit [ML^2]', scale=x_sc_pf) y_ax_pf = Axis(label='Minimum storage violation [ML]', scale=y_sc_pf, orientation='vertical') pareto_front = plt.scatter(results1_optim[:],results2_optim[:], scales={'x': x_sc_pf, 'y': y_sc_pf}, colors=['deepskyblue'], interactions={'hover':'tooltip','click': 'select'}) pareto_front.unselected_style={'opacity': 0.4} pareto_front.selected_style={'fill': 'red', 'stroke': 'yellow', 'width': '1125px', 'height': '125px'} def_tt = Tooltip(fields=['index','x', 'y'], labels=['index','Water deficit', 'Min storage'], formats=['.d','.1f', '.1f']) pareto_front.tooltip=def_tt fig_pf = plt.Figure(marks = [pareto_front],title = 'Interactive Pareto front', axes=[x_ax_pf, y_ax_pf], layout={'width': '400px', 'height': '400px'}, animation_duration=1000) if pareto_front.selected == []: pareto_front.selected = [0] pareto_front.observe(update_figure_2,'selected') # Initial simulation applting the point of the Pareto Fron selected by default u_ref,s_ref_1,s_ref_2 = sol_optim[pareto_front.selected[0]] x0 = [0, u_0] x1 = [s_ref_1, u_ref] x2 = [s_ref_2, u_ref] x3 = [1, u_1] param = [x0, x1, x2, x3, u_mean] u_frac = four_points_policy(param)/u_mean Qreg = {'releases' : {'file_name' : 'Reservoir_operating_policy.Operating_policy_functions', 'function' : 'four_points_policy', 'param': param}, 'inflows' : [], 'rel_inf' : []} Qenv, Qspill, u, I_reg, s, E = Res_sys_sim(I_hist, e_hist, s_0, s_min, s_max, env_min, d_hist, Qreg) # Fig 2a: Policy function s_frac = np.arange(0,1.01,0.01) x_sc_2a = LinearScale(min=0,max=1); y_sc_2a = LinearScale(min=0,max=u_max/u_mean); x_ax_2a = Axis(label='Storage fraction', scale=x_sc_2a); y_ax_2a = Axis(label='Release fraction', scale=y_sc_2a, orientation='vertical') policy_function = Lines(x = s_frac, y = u_frac , colors = ['blue'], scales = {'x': x_sc_2a, 'y': y_sc_2a}) fig_2a = plt.Figure(marks = [policy_function], title = 'Policy function', axes=[x_ax_2a, y_ax_2a], layout={'width': '400px', 'height': '375px'}, animation_duration=1000, scales={'x': x_sc_2a, 'y': y_sc_2a}) policy_function.observe(update_figure_2, ['x', 'y']) # Fig 2b: Releases vs Demand x_sc_2b = LinearScale(min=0,max=N); y_sc_2b = LinearScale(min=0,max=u_max); x_ax_2b = Axis(label='week', scale=x_sc_2b); y_ax_2b = Axis(label='ML/week', scale=y_sc_2b, orientation='vertical') demand = Bars(x = np.arange(1,N+1), y = d_hist, colors = ['gray'], scales = {'x': x_sc_2b, 'y': y_sc_2b}) releases = Bars(x = np.arange(1,N+1), y = u, colors = ['green'], scales = {'x': x_sc_2b, 'y': y_sc_2b}) TSD = (np.sum((np.maximum(d_hist-u,[0]*N))**2)).astype('int') fig_2b = plt.Figure(marks = [demand, releases], title = 'Supply vs Demand - TSD = '+str(TSD)+' ML^2', axes=[x_ax_2b, y_ax_2b], layout={'width': '950px', 'height': '250px'}, animation_duration=1000, scales={'x': x_sc_2b, 'y': y_sc_2b}) releases.observe(update_figure_2, ['x', 'y']) # Fig 2c: Storage x_sc_2c = LinearScale(); y_sc_2c = LinearScale(min=0,max=200); x_ax_2c = Axis(label='week', scale=x_sc_2c); y_ax_2c = Axis(label='ML', scale=y_sc_2c, orientation='vertical') storage = Lines(x = np.arange(0,N+1), y = s , colors = ['blue'], scales = {'x': x_sc_2c, 'y': y_sc_2c}, fill = 'bottom',fill_opacities = [0.8],fill_colors = ['blue']) max_storage = plt.plot(x=np.arange(0,N+1), y=[s_max]*(N+1), colors=['red'], scales={'x': x_sc_2c, 'y': y_sc_2c}) max_storage_label = plt.label(text = ['Max storage'], x=[0], y=[s_max+15], colors=['red']) min_storage = plt.plot(np.arange(0,N+1),rc, scales={'x': x_sc_2c, 'y': y_sc_2c}, colors=['red'],opacities = [1], line_style = 'dashed', fill = 'bottom',fill_opacities = [0.4],fill_colors = ['red'], stroke_width = 1) min_storage_label = plt.label(text = ['Min storage'], x=[0], y=[rc[0]-10], colors=['red']) MSV = (np.sum((np.maximum(rc-s,[0]*(N+1))))).astype('int') fig_2c = plt.Figure(marks = [storage,max_storage,max_storage_label, min_storage,min_storage_label], title = 'Reservoir storage volume - MSV = '+str(MSV)+' ML', axes=[x_ax_2c, y_ax_2c], layout={'width': '950px', 'height': '250px'}, animation_duration=1000, scales={'x': x_sc_2c, 'y': y_sc_2c}) storage.observe(update_figure_2, ['x', 'y']) return fig_pf, fig_2a,fig_2b,fig_2c
def Interactive_policy_manual(N, I_hist, e_hist, s_0, s_min, s_max, u_0, u_1, u_mean, u_max, env_min, d_hist, rc): #Function to update the release policy when changing the parameters with the sliders def update_operating_policy_1(s_ref_1,s_ref_2,u_ref): if s_ref_1 > s_ref_2: s_ref_1 = s_ref_2 x0 = [0, u_0] x1 = [s_ref_1, u_ref] x2 = [s_ref_2, u_ref] x3 = [1, u_1] param = [x0, x1, x2, x3, u_mean] u_frac = four_points_policy(param)/u_mean Qreg = {'releases' : {'file_name' : 'Reservoir_operating_policy.Operating_policy_functions', 'function' : 'four_points_policy', 'param': param}, 'inflows' : [], 'rel_inf' : []} Qenv, Qspill, u, I_reg, s, E = Res_sys_sim(I_hist, e_hist, s_0, s_min, s_max, env_min, d_hist, Qreg) TSD = (np.sum((np.maximum(d_hist-u,[0]*N))**2)).astype('int') fig_1b.title = 'Supply vs Demand - TSD = '+str(TSD)+' ML^2' MSV = (np.sum((np.maximum(rc-s,[0]*(N+1))))).astype('int') fig_1c.title = 'Reservoir storage volume - MSV = '+str(MSV)+' ML' return u_frac, Qenv, Qspill, u, I_reg, s # Function to update the figures when changing the parameters with the sliders def update_figure_1(change): policy_function.y = update_operating_policy_1(s_ref_1.value,s_ref_2.value,u_ref.value)[0] releases.y = update_operating_policy_1(s_ref_1.value,s_ref_2.value,u_ref.value)[3] storage.y = update_operating_policy_1(s_ref_1.value,s_ref_2.value,u_ref.value)[5] # Definition of the sliders u_ref = widgets.FloatSlider(min=0.5, max=u_1, value=1, step=0.05, description = 'u_ref: ', continuous_update = False) u_ref.observe(update_figure_1,names = 'value') s_ref_1 = widgets.FloatSlider(min=0, max=1, value=0.25, step=0.05, description = 's_ref_1: ', continuous_update=False) s_ref_1.observe(update_figure_1,names = 'value') s_ref_2 = widgets.FloatSlider(min=0, max=1, value=0.75, step=0.05, description = 's_ref_2: ', continuous_update=False) s_ref_2.observe(update_figure_1,names = 'value') # Initial simulation applying the default slider values of the parameters x0 = [0, u_0] x1 = [s_ref_1.value, u_ref.value] x2 = [s_ref_2.value, u_ref.value] x3 = [1, u_1] param = [x0, x1, x2, x3, u_mean] u_frac = four_points_policy(param)/u_mean Qreg = {'releases' : {'file_name' : 'Reservoir_operating_policy.Operating_policy_functions', 'function' : 'four_points_policy', 'param': param}, 'inflows' : [], 'rel_inf' : []} Qenv, Qspill, u, I_reg, s, E = Res_sys_sim(I_hist, e_hist, s_0, s_min, s_max, env_min, d_hist, Qreg) ### Figures ### # Fig 1a: Policy function s_frac = np.arange(0,1.01,0.01) x_sc_1a = LinearScale(min=0,max=1); y_sc_1a = LinearScale(min=0,max=u_1); x_ax_1a = Axis(label='Storage fraction', scale=x_sc_1a); y_ax_1a = Axis(label='Release fraction', scale=y_sc_1a, orientation='vertical') policy_function = Lines(x = s_frac, y = u_frac, colors = ['blue'], scales = {'x': x_sc_1a, 'y': y_sc_1a}) fig_1a = plt.Figure(marks = [policy_function], title = 'Policy function', axes=[x_ax_1a, y_ax_1a], layout={'width': '400px', 'height': '375px'}, animation_duration=1000, scales={'x': x_sc_1a, 'y': y_sc_1a}) policy_function.observe(update_figure_1, ['x', 'y']) # Fig 1b: Releases vs Demand x_sc_1b = LinearScale(min=0,max=N); y_sc_1b = LinearScale(min=0,max=u_max); x_ax_1b = Axis(label='week', scale=x_sc_1b); y_ax_1b = Axis(label='ML/week', scale=y_sc_1b, orientation='vertical') demand = Bars(x = np.arange(1,N+1), y = d_hist, colors = ['gray'], scales = {'x': x_sc_1b, 'y': y_sc_1b}) releases = Bars(x = np.arange(1,N+1), y = u, colors = ['green'], scales = {'x': x_sc_1b, 'y': y_sc_1b}) TSD = (np.sum((np.maximum(d_hist-u,[0]*N))**2)).astype('int') fig_1b = plt.Figure(marks = [demand, releases], title = 'Supply vs Demand - TSD = '+str(TSD)+' ML^2', axes=[x_ax_1b, y_ax_1b], layout={'width': '950px', 'height': '250px'}, animation_duration=1000, scales={'x': x_sc_1b, 'y': y_sc_1b}) releases.observe(update_figure_1, ['x', 'y']) # Fig 1c: Storage x_sc_1c = LinearScale(); y_sc_1c = LinearScale(min=0,max=200); x_ax_1c = Axis(label='week', scale=x_sc_1c); y_ax_1c = Axis(label='ML', scale=y_sc_1c, orientation='vertical') storage = Lines(x = np.arange(0,N+1), y = s , colors = ['blue'], scales = {'x': x_sc_1c, 'y': y_sc_1c}, fill = 'bottom',fill_opacities = [0.8],fill_colors = ['blue']) max_storage = plt.plot(x=np.arange(0,N+1), y=[s_max]*(N+1), colors=['red'], scales={'x': x_sc_1c, 'y': y_sc_1c}) max_storage_label = plt.label(text = ['Max storage'], x=[0], y=[s_max+15], colors=['red']) min_storage = plt.plot(np.arange(0,N+1),rc, scales={'x': x_sc_1c, 'y': y_sc_1c}, colors=['red'],opacities = [1], line_style = 'dashed', fill = 'bottom',fill_opacities = [0.4],fill_colors = ['red'], stroke_width = 1) min_storage_label = plt.label(text = ['Min storage'], x=[0], y=[rc[0]-10], colors=['red']) MSV = (np.sum((np.maximum(rc-s,[0]*(N+1))))).astype('int') fig_1c = plt.Figure(marks = [storage,max_storage,max_storage_label, min_storage,min_storage_label], title = 'Reservoir storage volume - MSV = '+str(MSV)+' ML', axes=[x_ax_1c, y_ax_1c], layout={'width': '950px', 'height': '250px'}, animation_duration=1000, scales={'x': x_sc_1c, 'y': y_sc_1c}) storage.observe(update_figure_1, ['x', 'y']) return fig_1a,fig_1b,fig_1c, u_ref,s_ref_1,s_ref_2
def Forecast_ensemble(N, members_num, I_for, d_for): x_sc_1 = LinearScale() y_sc_1 = LinearScale(min=0, max=40) x_ax_1 = Axis(label='week', scale=x_sc_1, tick_values=np.arange(1, 9), tick_style={ 'fill': 'black', 'font-size': 16 }) y_ax_1 = Axis(label='ML/week', scale=y_sc_1, orientation='vertical', tick_style={ 'fill': 'black', 'font-size': 16 }) inflow_forecast_9 = plt.plot(x=np.arange(1, N + 1), y=I_for, colors=['deepskyblue'], stroke_width=4, opacities=[1] * members_num, display_legend=False, scales={ 'x': x_sc_1, 'y': y_sc_1 }) fig_9a = plt.Figure(marks=[inflow_forecast_9], title='Inflow forecast for the next 8 weeks', axes=[x_ax_1, y_ax_1], layout={ 'min_width': '1000px', 'max_height': '300px' }, scales={ 'x': x_sc_1, 'y': y_sc_1 }, legend_location='bottom-left') demand_forecast_9 = plt.plot(x=np.arange(1, N + 1), y=d_for, colors=['ligthgreen'], stroke_width=4, opacities=[1] * members_num, display_legend=False, scales={ 'x': x_sc_1, 'y': y_sc_1 }) fig_9b = plt.Figure(marks=[demand_forecast_9], title='Demand forecast for the next 8 weeks', axes=[x_ax_1, y_ax_1], layout={ 'min_width': '1000px', 'max_height': '300px' }, scales={ 'x': x_sc_1, 'y': y_sc_1 }, legend_location='bottom-left') return fig_9a, fig_9b
def Observed_inflows(N, members_num, I_sel, d_sel, I_for, d_for): I_act = np.array([[14.85, 20.17, 21.84, 20.59, 14.85, 20.17, 21.84, 20.59]]) T_act = np.array([[24.81, 22.37, 20.13, 18.91, 24.81, 22.37, 20.13, 18.91]]) E_act = T_act / 10 d_act = T_act x_sc_1 = LinearScale() y_sc_1 = LinearScale(min=0, max=40) x_ax_1 = Axis(label='week', scale=x_sc_1, tick_values=np.arange(1, 9), tick_style={ 'fill': 'black', 'font-size': 16 }) y_ax_1 = Axis(label='ML/week', scale=y_sc_1, orientation='vertical', tick_style={ 'fill': 'black', 'font-size': 16 }) inflow_forecast_3 = plt.plot(x=np.arange(1, N + 1), y=I_for, colors=['deepskyblue'], stroke_width=4, opacities=[0.4] * members_num, display_legend=False, scales={ 'x': x_sc_1, 'y': y_sc_1 }) sel_inflow_3 = plt.plot(np.arange(1, N + 1), I_sel, scales={ 'x': x_sc_1, 'y': y_sc_1 }, colors=['darkblue'], stroke_width=4, line_style='solid', marker=None, marker_size=20, labels=['forecast'], display_legend=True) act_inflow_3 = plt.plot(np.arange(1, N + 1), I_act, scales={ 'x': x_sc_1, 'y': y_sc_1 }, colors=['black'], stroke_width=4, marker=None, marker_size=40, labels=['actual'], display_legend=True) fig_3a = plt.Figure(marks=[inflow_forecast_3, sel_inflow_3, act_inflow_3], title='Inflows in the last 8 weeks', axes=[x_ax_1, y_ax_1], layout={ 'min_width': '1000px', 'max_height': '300px' }, scales={ 'x': x_sc_1, 'y': y_sc_1 }, legend_location='bottom-left') demand_forecast_3 = plt.plot(x=np.arange(1, N + 1), y=d_for, colors=['lightgreen'], stroke_width=4, opacities=[0.4] * members_num, display_legend=False, scales={ 'x': x_sc_1, 'y': y_sc_1 }) sel_demand_3 = plt.plot(np.arange(1, N + 1), d_sel, scales={ 'x': x_sc_1, 'y': y_sc_1 }, colors=['darkolivegreen'], stroke_width=4, line_style='solid', label='selected', marker=None, marker_size=20, labels=['forecast'], display_legend=True) act_demand_3 = plt.plot(np.arange(1, N + 1), d_act, scales={ 'x': x_sc_1, 'y': y_sc_1 }, colors=['black'], stroke_width=4, label='actual', marker=None, marker_size=40, labels=['actual'], display_legend=True) fig_3b = plt.Figure(marks=[demand_forecast_3, sel_demand_3, act_demand_3], title='Demand in the last 8 weeks', axes=[x_ax_1, y_ax_1], layout={ 'min_width': '1000px', 'max_height': '300px' }, scales={ 'x': x_sc_1, 'y': y_sc_1 }, legend_location='bottom-left') return I_act, T_act, E_act, d_act, fig_3a, fig_3b
def Ensemble_member_sel(N, members_num, I_for, d_for): I_sel = np.array([[0] * N]) d_sel = np.array([[0] * N]) def on_element_click_event_1a(self, target): click_elem_id = list(target.values())[1]['index'] line_opacities = [0.4] * members_num line_opacities[click_elem_id] = 1 inflow_forecast.opacities = line_opacities line_colors = ['deepskyblue'] * members_num line_colors[click_elem_id] = 'darkblue' inflow_forecast.colors = line_colors for t in range(N): I_sel[0, t] = I_for[click_elem_id][t] fig_1a.title = 'Inflow forecast - Chosen forecast member = ' + str( click_elem_id) fig_1a.title_style = { 'fill': 'black', 'stroke': 'black', 'font-size': '20px' } def on_element_click_event_1b(self, target): click_elem_id = list(target.values())[1]['index'] line_opacities = [0.4] * members_num line_opacities[click_elem_id] = 1 demand_forecast.opacities = line_opacities line_colors = ['lightgreen'] * members_num line_colors[click_elem_id] = 'darkolivegreen' demand_forecast.colors = line_colors # line_styles = ['solid']*members_num # line_styles[click_elem_id] = 'dash_dotted' # demand_forecast.line_styles = line_styles for t in range(N): d_sel[0, t] = d_for[click_elem_id][t] fig_1b.title = 'Demand forecast - Chosen forecast member = ' + str( click_elem_id) fig_1b.title_style = { 'fill': 'black', 'stroke': 'black', 'font-size': '20px' } def on_hover_1a(self, target): hover_elem_id = list(target.values())[1]['index'] line_opacities = [0.4] * members_num line_opacities[hover_elem_id] = 1 inflow_forecast.opacities = line_opacities def on_hover_1b(self, target): hover_elem_id = list(target.values())[1]['index'] line_opacities = [0.4] * members_num line_opacities[hover_elem_id] = 1 demand_forecast.opacities = line_opacities x_sc_1 = LinearScale() y_sc_1 = LinearScale(min=0, max=40) x_ax_1 = Axis(label='week', scale=x_sc_1, tick_values=np.arange(1, N + 1), tick_style={ 'fill': 'black', 'font-size': 16 }) y_ax_1 = Axis(label='ML/week', scale=y_sc_1, orientation='vertical', tick_style={ 'fill': 'black', 'font-size': 16 }) def_tt = Tooltip(fields=['index'], formats=['.0f'], labels=['Forecast member']) inflow_forecast = plt.plot(x=np.arange(1, N + 1), y=I_for, colors=['deepskyblue'], stroke_width=4, opacities=[0.4] * members_num, tooltip=def_tt, display_legend=False, scales={ 'x': x_sc_1, 'y': y_sc_1 }) inflow_forecast.on_element_click(on_element_click_event_1a) # inflow_forecast.on_hover(on_hover_1a) fig_1a = plt.Figure(marks=[inflow_forecast], title='Inflow forecast - Choose a forecast member:', title_style={ 'fill': 'blue', 'font-size': '20px' }, axes=[x_ax_1, y_ax_1], layout={ 'min_width': '1000px', 'max_height': '300px' }, scales={ 'x': x_sc_1, 'y': y_sc_1 }) demand_forecast = plt.plot(np.arange(1, N + 1), d_for, colors=['lightgreen'], stroke_width=4, opacities=[0.4] * members_num, tooltip=def_tt, scales={ 'x': x_sc_1, 'y': y_sc_1 }) demand_forecast.on_element_click(on_element_click_event_1b) # demand_forecast.on_hover(on_hover_1b) fig_1b = plt.Figure(marks=[demand_forecast], title='Demand forecast - Choose a forecast member:', title_style={ 'fill': 'dimgray', 'font-size': '20px' }, axes=[x_ax_1, y_ax_1], layout={ 'min_width': '1000px', 'max_height': '300px' }, scales={ 'x': x_sc_1, 'y': y_sc_1 }) return fig_1a, fig_1b, I_sel, d_sel