def plot_trajectory(self, initials, duration, plot_durations=None, dt=None, show=False, with_plot=True, with_return=False): utils.output('I am plotting the trajectory ...') # check the initial values initials = utils.check_initials(initials, self.target_var_names + self.target_par_names) # 2. format the running duration assert isinstance(duration, (int, float)) # 3. format the plot duration plot_durations = utils.check_plot_durations(plot_durations, duration, initials) # 5. run the network dt = bm.get_dt() if dt is None else dt traject_model = utils.TrajectModel(initial_vars=initials, integrals=self._std_integrators, dt=dt) mon_res = traject_model.run(duration=duration) if with_plot: assert len(self.target_par_names) <= 2 # plots for i, initial in enumerate(zip(*list(initials.values()))): # legend legend = f'$traj_{i}$: ' for j, key in enumerate(self.target_var_names): legend += f'{key}={initial[j]}, ' legend = legend[:-2] # visualization start = int(plot_durations[i][0] / dt) end = int(plot_durations[i][1] / dt) p1_var = self.target_par_names[0] if len(self.target_par_names) == 1: lines = plt.plot(mon_res[self.x_var][start: end, i], mon_res[p1_var][start: end, i], label=legend) elif len(self.target_par_names) == 2: p2_var = self.target_par_names[1] lines = plt.plot(mon_res[self.x_var][start: end, i], mon_res[p1_var][start: end, i], mon_res[p2_var][start: end, i], label=legend) else: raise ValueError utils.add_arrow(lines[0]) # # visualization of others # plt.xlabel(self.x_var) # plt.ylabel(self.target_par_names[0]) # scale = (self.lim_scale - 1.) / 2 # plt.xlim(*utils.rescale(self.target_vars[self.x_var], scale=scale)) # plt.ylim(*utils.rescale(self.target_vars[self.target_par_names[0]], scale=scale)) plt.legend() if show: plt.show() if with_return: return mon_res
def plot_trajectory(self, initials, duration, plot_durations=None, dt=None, show=False, with_plot=True, with_return=False): utils.output('I am plotting the trajectory ...') # check the initial values initials = utils.check_initials(initials, self.target_var_names + self.target_par_names) # 2. format the running duration assert isinstance(duration, (int, float)) # 3. format the plot duration plot_durations = utils.check_plot_durations(plot_durations, duration, initials) # 5. run the network dt = bm.get_dt() if dt is None else dt traject_model = utils.TrajectModel(initial_vars=initials, integrals=self._std_integrators, dt=dt) mon_res = traject_model.run(duration=duration) if with_plot: assert len(self.target_par_names) <= 1 # plots for i, initial in enumerate(zip(*list(initials.values()))): # legend legend = f'$traj_{i}$: ' for j, key in enumerate(self.target_var_names): legend += f'{key}={initial[j]}, ' legend = legend[:-2] start = int(plot_durations[i][0] / dt) end = int(plot_durations[i][1] / dt) # visualization plt.figure(self.x_var) lines = plt.plot(mon_res[self.target_par_names[0]][start: end, i], mon_res[self.x_var][start: end, i], label=legend) utils.add_arrow(lines[0]) plt.figure(self.y_var) lines = plt.plot(mon_res[self.target_par_names[0]][start: end, i], mon_res[self.y_var][start: end, i], label=legend) utils.add_arrow(lines[0]) plt.figure(self.x_var) plt.legend() plt.figure(self.y_var) plt.legend() if show: plt.show() if with_return: return mon_res
def plot_limit_cycle_by_sim(self, initials, duration, tol=0.001, show=False): """Plot trajectories according to the settings. Parameters ---------- initials : list, tuple The initial value setting of the targets. It can be a tuple/list of floats to specify each value of dynamical variables (for example, ``(a, b)``). It can also be a tuple/list of tuple to specify multiple initial values (for example, ``[(a1, b1), (a2, b2)]``). duration : int, float, tuple, list The running duration. Same with the ``duration`` in ``NeuGroup.run()``. It can be a int/float (``t_end``) to specify the same running end time, or it can be a tuple/list of int/float (``(t_start, t_end)``) to specify the start and end simulation time. Or, it can be a list of tuple (``[(t1_start, t1_end), (t2_start, t2_end)]``) to specify the specific start and end simulation time for each initial value. show : bool Whether show or not. """ print('plot limit cycle ...') # 1. format the initial values if isinstance(initials, dict): initials = [initials] elif isinstance(initials, (list, tuple)): if isinstance(initials[0], (int, float)): initials = [{ self.dvar_names[i]: v for i, v in enumerate(initials) }] elif isinstance(initials[0], dict): initials = initials elif isinstance(initials[0], (tuple, list)) and isinstance( initials[0][0], (int, float)): initials = [{ self.dvar_names[i]: v for i, v in enumerate(init) } for init in initials] else: raise ValueError else: raise ValueError # 2. format the running duration if isinstance(duration, (int, float)): duration = [(0, duration) for _ in range(len(initials))] elif isinstance(duration[0], (int, float)): duration = [duration for _ in range(len(initials))] else: assert len(duration) == len(initials) # 5. run the network for init_i, initial in enumerate(initials): traj_group = Trajectory(size=1, integrals=self.model.integrals, target_vars=initial, fixed_vars=self.fixed_vars, pars_update=self.pars_update, scope=self.model.scopes) # 5.2 run the model traj_group.run( duration=duration[init_i], report=False, ) x_data = traj_group.mon[self.x_var][:, 0] y_data = traj_group.mon[self.y_var][:, 0] max_index = utils.find_indexes_of_limit_cycle_max(x_data, tol=tol) if max_index[0] != -1: x_cycle = x_data[max_index[0]:max_index[1]] y_cycle = y_data[max_index[0]:max_index[1]] # 5.5 visualization lines = plt.plot(x_cycle, y_cycle, label='limit cycle') utils.add_arrow(lines[0]) else: print(f'No limit cycle found for initial value {initial}') # 6. visualization plt.xlabel(self.x_var) plt.ylabel(self.y_var) scale = (self.options.lim_scale - 1.) / 2 plt.xlim(*utils.rescale(self.target_vars[self.x_var], scale=scale)) plt.ylim(*utils.rescale(self.target_vars[self.y_var], scale=scale)) plt.legend() if show: plt.show()
def plot_trajectory(self, initials, duration, plot_duration=None, axes='v-v', show=False): """Plot trajectories according to the settings. Parameters ---------- initials : list, tuple, dict The initial value setting of the targets. It can be a tuple/list of floats to specify each value of dynamical variables (for example, ``(a, b)``). It can also be a tuple/list of tuple to specify multiple initial values (for example, ``[(a1, b1), (a2, b2)]``). duration : int, float, tuple, list The running duration. Same with the ``duration`` in ``NeuGroup.run()``. It can be a int/float (``t_end``) to specify the same running end time, or it can be a tuple/list of int/float (``(t_start, t_end)``) to specify the start and end simulation time. Or, it can be a list of tuple (``[(t1_start, t1_end), (t2_start, t2_end)]``) to specify the specific start and end simulation time for each initial value. plot_duration : tuple, list, optional The duration to plot. It can be a tuple with ``(start, end)``. It can also be a list of tuple ``[(start1, end1), (start2, end2)]`` to specify the plot duration for each initial value running. axes : str The axes to plot. It can be: - 'v-v' Plot the trajectory in the 'x_var'-'y_var' axis. - 't-v' Plot the trajectory in the 'time'-'var' axis. show : bool Whether show or not. """ print('plot trajectory ...') if axes not in ['v-v', 't-v']: raise errors.ModelUseError( f'Unknown axes "{axes}", only support "v-v" and "t-v".') # 1. format the initial values if isinstance(initials, dict): initials = [initials] elif isinstance(initials, (list, tuple)): if isinstance(initials[0], (int, float)): initials = [{ self.dvar_names[i]: v for i, v in enumerate(initials) }] elif isinstance(initials[0], dict): initials = initials elif isinstance(initials[0], (tuple, list)) and isinstance( initials[0][0], (int, float)): initials = [{ self.dvar_names[i]: v for i, v in enumerate(init) } for init in initials] else: raise ValueError else: raise ValueError # 2. format the running duration if isinstance(duration, (int, float)): duration = [(0, duration) for _ in range(len(initials))] elif isinstance(duration[0], (int, float)): duration = [duration for _ in range(len(initials))] else: assert len(duration) == len(initials) # 3. format the plot duration if plot_duration is None: plot_duration = duration if isinstance(plot_duration[0], (int, float)): plot_duration = [plot_duration for _ in range(len(initials))] else: assert len(plot_duration) == len(initials) # 5. run the network for init_i, initial in enumerate(initials): traj_group = Trajectory(size=1, integrals=self.model.integrals, target_vars=initial, fixed_vars=self.fixed_vars, pars_update=self.pars_update, scope=self.model.scopes) # 5.2 run the model traj_group.run( duration=duration[init_i], report=False, ) # 5.3 legend legend = f'$traj_{init_i}$: ' for key in self.dvar_names: legend += f'{key}={initial[key]}, ' legend = legend[:-2] # 5.4 trajectory start = int(plot_duration[init_i][0] / backend.get_dt()) end = int(plot_duration[init_i][1] / backend.get_dt()) # 5.5 visualization if axes == 'v-v': lines = plt.plot(traj_group.mon[self.x_var][start:end, 0], traj_group.mon[self.y_var][start:end, 0], label=legend) utils.add_arrow(lines[0]) else: plt.plot(traj_group.mon.ts[start:end], traj_group.mon[self.x_var][start:end, 0], label=legend + f', {self.x_var}') plt.plot(traj_group.mon.ts[start:end], traj_group.mon[self.y_var][start:end, 0], label=legend + f', {self.y_var}') # 6. visualization if axes == 'v-v': plt.xlabel(self.x_var) plt.ylabel(self.y_var) scale = (self.options.lim_scale - 1.) / 2 plt.xlim(*utils.rescale(self.target_vars[self.x_var], scale=scale)) plt.ylim(*utils.rescale(self.target_vars[self.y_var], scale=scale)) plt.legend() else: plt.legend(title='Initial values') if show: plt.show()
def plot_limit_cycle_by_sim(self, initials, duration, tol=0.01, show=False, dt=None): """Plot trajectories according to the settings. Parameters ---------- initials : list, tuple The initial value setting of the targets. - It can be a tuple/list of floats to specify each value of dynamical variables (for example, ``(a, b)``). - It can also be a tuple/list of tuple to specify multiple initial values (for example, ``[(a1, b1), (a2, b2)]``). duration : int, float, tuple, list The running duration. Same with the ``duration`` in ``NeuGroup.run()``. - It can be a int/float (``t_end``) to specify the same running end time, - Or it can be a tuple/list of int/float (``(t_start, t_end)``) to specify the start and end simulation time. - Or, it can be a list of tuple (``[(t1_start, t1_end), (t2_start, t2_end)]``) to specify the specific start and end simulation time for each initial value. show : bool Whether show or not. """ utils.output('I am plotting the limit cycle ...') # 1. format the initial values initials = utils.check_initials(initials, self.target_var_names) # 2. format the running duration assert isinstance(duration, (int, float)) dt = math.get_dt() if dt is None else dt traject_model = utils.TrajectModel(initial_vars=initials, integrals={ self.x_var: self.F_int_x, self.y_var: self.F_int_y }, dt=dt) mon_res = traject_model.run(duration=duration) # 5. run the network for init_i, initial in enumerate(zip(*list(initials.values()))): # 5.2 run the model x_data = mon_res[self.x_var][:, init_i] y_data = mon_res[self.y_var][:, init_i] max_index = utils.find_indexes_of_limit_cycle_max(x_data, tol=tol) if max_index[0] != -1: x_cycle = x_data[max_index[0]:max_index[1]] y_cycle = y_data[max_index[0]:max_index[1]] # 5.5 visualization lines = plt.plot(x_cycle, y_cycle, label='limit cycle') utils.add_arrow(lines[0]) else: utils.output( f'No limit cycle found for initial value {initial}') # 6. visualization plt.xlabel(self.x_var) plt.ylabel(self.y_var) scale = (self.lim_scale - 1.) / 2 plt.xlim(*utils.rescale(self.target_vars[self.x_var], scale=scale)) plt.ylim(*utils.rescale(self.target_vars[self.y_var], scale=scale)) plt.legend() if show: plt.show()
def plot_trajectory(self, initials, duration, plot_durations=None, axes='v-v', dt=None, show=False, with_plot=True, with_return=False, **kwargs): """Plot trajectories according to the settings. Parameters ---------- initials : list, tuple, dict The initial value setting of the targets. It can be a tuple/list of floats to specify each value of dynamical variables (for example, ``(a, b)``). It can also be a tuple/list of tuple to specify multiple initial values (for example, ``[(a1, b1), (a2, b2)]``). duration : int, float, tuple, list The running duration. Same with the ``duration`` in ``NeuGroup.run()``. - It can be a int/float (``t_end``) to specify the same running end time, - Or it can be a tuple/list of int/float (``(t_start, t_end)``) to specify the start and end simulation time. - Or, it can be a list of tuple (``[(t1_start, t1_end), (t2_start, t2_end)]``) to specify the specific start and end simulation time for each initial value. plot_durations : tuple, list, optional The duration to plot. It can be a tuple with ``(start, end)``. It can also be a list of tuple ``[(start1, end1), (start2, end2)]`` to specify the plot duration for each initial value running. axes : str The axes to plot. It can be: - 'v-v': Plot the trajectory in the 'x_var'-'y_var' axis. - 't-v': Plot the trajectory in the 'time'-'var' axis. show : bool Whether show or not. """ utils.output('I am plotting the trajectory ...') if axes not in ['v-v', 't-v']: raise errors.AnalyzerError( f'Unknown axes "{axes}", only support "v-v" and "t-v".') # check the initial values initials = utils.check_initials(initials, self.target_var_names) # 2. format the running duration assert isinstance(duration, (int, float)) # 3. format the plot duration plot_durations = utils.check_plot_durations(plot_durations, duration, initials) # 5. run the network dt = math.get_dt() if dt is None else dt traject_model = utils.TrajectModel(initial_vars=initials, integrals={ self.x_var: self.F_int_x, self.y_var: self.F_int_y }, dt=dt) mon_res = traject_model.run(duration=duration) if with_plot: # plots for i, initial in enumerate(zip(*list(initials.values()))): # legend legend = f'$traj_{i}$: ' for j, key in enumerate(self.target_var_names): legend += f'{key}={round(float(initial[j]), 4)}, ' legend = legend[:-2] # visualization start = int(plot_durations[i][0] / dt) end = int(plot_durations[i][1] / dt) if axes == 'v-v': lines = plt.plot(mon_res[self.x_var][start:end, i], mon_res[self.y_var][start:end, i], label=legend, **kwargs) utils.add_arrow(lines[0]) else: plt.plot(mon_res.ts[start:end], mon_res[self.x_var][start:end, i], label=legend + f', {self.x_var}', **kwargs) plt.plot(mon_res.ts[start:end], mon_res[self.y_var][start:end, i], label=legend + f', {self.y_var}', **kwargs) # visualization of others if axes == 'v-v': plt.xlabel(self.x_var) plt.ylabel(self.y_var) scale = (self.lim_scale - 1.) / 2 plt.xlim( *utils.rescale(self.target_vars[self.x_var], scale=scale)) plt.ylim( *utils.rescale(self.target_vars[self.y_var], scale=scale)) plt.legend() else: plt.legend(title='Initial values') if show: plt.show() if with_return: return mon_res
def plot_trajectory(self, initials, duration, plot_duration=None, show=False): """Plot trajectories according to the settings. Parameters ---------- initials : list, tuple The initial value setting of the targets. It can be a tuple/list of floats to specify each value of dynamical variables (for example, ``(a, b)``). It can also be a tuple/list of tuple to specify multiple initial values (for example, ``[(a1, b1), (a2, b2)]``). duration : int, float, tuple, list The running duration. Same with the ``duration`` in ``NeuGroup.run()``. It can be a int/float (``t_end``) to specify the same running end time, or it can be a tuple/list of int/float (``(t_start, t_end)``) to specify the start and end simulation time. Or, it can be a list of tuple (``[(t1_start, t1_end), (t2_start, t2_end)]``) to specify the specific start and end simulation time for each initial value. plot_duration : tuple/list of tuple, optional The duration to plot. It can be a tuple with ``(start, end)``. It can also be a list of tuple ``[(start1, end1), (start2, end2)]`` to specify the plot duration for each initial value running. show : bool Whether show or not. """ print('plot trajectory ...') # 1. format the initial values all_vars = self.fast_var_names + self.slow_var_names if isinstance(initials, dict): initials = [initials] elif isinstance(initials, (list, tuple)): if isinstance(initials[0], (int, float)): initials = [{all_vars[i]: v for i, v in enumerate(initials)}] elif isinstance(initials[0], dict): initials = initials elif isinstance(initials[0], (tuple, list)) and isinstance( initials[0][0], (int, float)): initials = [{all_vars[i]: v for i, v in enumerate(init)} for init in initials] else: raise ValueError else: raise ValueError for initial in initials: if len(initial) != len(all_vars): raise errors.AnalyzerError( f'Should provide all fast-slow variables ({all_vars}) ' f' initial values, but we only get initial values for ' f'variables {list(initial.keys())}.') # 2. format the running duration if isinstance(duration, (int, float)): duration = [(0, duration) for _ in range(len(initials))] elif isinstance(duration[0], (int, float)): duration = [duration for _ in range(len(initials))] else: assert len(duration) == len(initials) # 3. format the plot duration if plot_duration is None: plot_duration = duration if isinstance(plot_duration[0], (int, float)): plot_duration = [plot_duration for _ in range(len(initials))] else: assert len(plot_duration) == len(initials) # 5. run the network for init_i, initial in enumerate(initials): traj_group = Trajectory(size=1, integrals=self.model.integrals, target_vars=initial, fixed_vars=self.fixed_vars, pars_update=self.pars_update, scope=self.model.scopes) traj_group.run(duration=duration[init_i], report=False) # 5.3 legend legend = f'$traj_{init_i}$: ' for key in all_vars: legend += f'{key}={initial[key]}, ' legend = legend[:-2] # 5.4 trajectory start = int(plot_duration[init_i][0] / backend.get_dt()) end = int(plot_duration[init_i][1] / backend.get_dt()) # 5.5 visualization for var_name in self.fast_var_names: s0 = traj_group.mon[self.slow_var_names[0]][start:end, 0] fast = traj_group.mon[var_name][start:end, 0] fig = plt.figure(var_name) if len(self.slow_var_names) == 1: lines = plt.plot(s0, fast, label=legend) utils.add_arrow(lines[0]) # middle = int(s0.shape[0] / 2) # plt.arrow(s0[middle], fast[middle], # s0[middle + 1] - s0[middle], fast[middle + 1] - fast[middle], # shape='full') elif len(self.slow_var_names) == 2: fig.gca(projection='3d') s1 = traj_group.mon[self.slow_var_names[1]][start:end, 0] plt.plot(s0, s1, fast, label=legend) else: raise errors.AnalyzerError # 6. visualization for var_name in self.fast_vars.keys(): fig = plt.figure(var_name) # scale = (self.lim_scale - 1.) / 2 if len(self.slow_var_names) == 1: # plt.xlim(*utils.rescale(self.slow_vars[self.slow_var_names[0]], scale=scale)) # plt.ylim(*utils.rescale(self.fast_vars[var_name], scale=scale)) plt.xlabel(self.slow_var_names[0]) plt.ylabel(var_name) elif len(self.slow_var_names) == 2: ax = fig.gca(projection='3d') # ax.set_xlim(*utils.rescale(self.slow_vars[self.slow_var_names[0]], scale=scale)) # ax.set_ylim(*utils.rescale(self.slow_vars[self.slow_var_names[1]], scale=scale)) # ax.set_zlim(*utils.rescale(self.fast_vars[var_name], scale=scale)) ax.set_xlabel(self.slow_var_names[0]) ax.set_ylabel(self.slow_var_names[1]) ax.set_zlabel(var_name) plt.legend() if show: plt.show()