def plot_points(plt, positions, status, title=None): x = [p[0] for p in positions] y = [p[1] for p in positions] if status is not None: c = [STATE_COLORS[s] for s in status] sizes = [1, 16, 9, 9, 4, 16] scatter = plt.scatter(x=x, y=y, c=status, alpha=0.9, s=[sizes[s] + 4 for s in status]) running = Counter(status) descriptions = list(STATE_DESCRIPTIONS.values()) running_totals = [(descriptions[k] + " (" + str(v) + ")", k) for k, v in running.items()] running_totals.sort(key=lambda rt: rt[1]) labels = [desc for desc, _ in running_totals] plt.legend(handles=scatter.legend_elements()[0], labels=labels, loc='upper left') if title: plt.title(title) else: scatter = plt.scatter(x=x, y=y) return scatter
def simulate(params, plt=None, plot_hourly=None, xlabel=None): if plot_hourly is None: plot_hourly = params['geometry']['n'] < 50000 # Hack, remove # Initialize a city's geography and its denizens num, num_initially_infected = int(params['geometry']['n']), int( params['geometry']['i']) num_times_of_day = int(params['motion']['t']) precision = int(params['geometry']['p']) home, work = home_and_work_locations(geometry_params=params['geometry'], num=num) positions = nudge(home, w=0.05 * params['motion']['w']) status = np.random.permutation([INFECTED] * num_initially_infected + [VULNERABLE] * (num - num_initially_infected)) day_fraction = 1.0 / num_times_of_day # Population drifts to work and back, incurring viral load based on proximity to others who are infected day = 0 while any(s in [INFECTED, POSITIVE, SYMPTOMATIC] for s in status): day = day + 1 for step_no, time_of_day in enumerate(times_of_day(num_times_of_day)): stationary = [s in [DECEASED, POSITIVE] for s in status] attractors = destinations(status, time_of_day, home, work) positions = evolve_positions(positions=positions, motion_params=params['motion'], attractors=attractors, day_fraction=day_fraction, stationary=stationary) exposed = newly_exposed(positions=positions, status=status, precision=precision) status = contact_progression(status=status, health_params=params['health'], exposed=exposed) status = individual_progression(status, health_params=params['health'], day_fraction=day_fraction) if plt and (plot_hourly or step_no % 12 == 0): plt.clf() plot_points(plt=plt, positions=positions, status=status, title="Day " + str(day) + ':' + str(time_of_day * num_times_of_day)) b = params['geometry']['b'] plt.axis([-b, b, -b, b]) if xlabel: plt.xlabel(xlabel) plt.show(block=False) plt.pause(0.01) pprint( Counter([list(STATE_DESCRIPTIONS.values())[s] for s in status]))
def simulate(params, plt=None, hourly=None, xlabel=None, callback=plot_callback, home=None, work=None, positions=None, stopping_i=None, stopping_t=None): """ OU Pandemic simulation :param params: dict of dict as per pandemic.conventions :param plt: Handle to matplotlib plot :param hourly: Bool Set False to speed up, True to see commuting :param xlabel: str Label for plot :param callback: Any function taking home, work, day, params, positions, status (e.g. for plotting, saving etc) :return: None Use the callback """ if stopping_i is None: import math stopping_i = int(math.ceil(0.7 * params['geometry']['i'])) if hourly is None: hourly = params['geometry']['n'] < 50000 # Hack, remove if stopping_t is None: stopping_t = 150 # Initialize a city's geography and its denizens num, num_initially_infected = int(params['geometry']['n']),int(params['geometry']['i']) num_times_of_day = int(params['motion']['t']) precision = int(params['geometry']['p']) if home is None or work is None: home, work = home_and_work_locations(geometry_params=params['geometry'],num=num) if positions is None: positions = nudge(home,w=0.05*params['motion']['w']) status = np.random.permutation([INFECTED]*num_initially_infected +[VULNERABLE]*(num-num_initially_infected)) time_step = 1.0/num_times_of_day day = 0 killed = False while sum( s in [ INFECTED ] for s in status )>=stopping_i and day<stopping_t and not killed: day = day+1 for step_no, day_fraction in enumerate(times_of_day(num_times_of_day)): stationary = [ s in [DECEASED, POSITIVE] for s in status ] attractors = destinations(status, day_fraction, home, work) positions = evolve_positions(positions=positions, motion_params=params['motion'], attractors=attractors, time_step=time_step , stationary=stationary ) exposed = newly_exposed(positions=positions, status=status, precision=precision) status = contact_progression(status=status, health_params=params['health'], exposed=exposed) status = individual_progression(status, health_params=params['health'], day_fraction=time_step ) if callback: signal = callback(day=day, day_fraction=day_fraction, home=home, work=work, positions=positions, status=status, params=params, step_no=step_no, hourly=hourly, plt=plt, xlabel=xlabel) if signal is not None: if 'kill' in signal: killed = True if 'lockdown' in signal: work = [ h for h in home ] if 'params' in signal: params.update(signal['params']) pprint(Counter([list(STATE_DESCRIPTIONS.values())[s] for s in status]))
def plot_metrics(self, plt, logarithmic, differences=False): metrics = list(zip(*self.metric_history))[1:] if len(metrics[0]) > 3: for m in metrics[1:-2]: if differences: plt.plot(self.time_history[1:], list(np.diff(m))) plt.set_ylabel('Daily change') else: plt.plot(self.time_history, m) plt.set_ylabel('Cumulative') if logarithmic: plt.set_yscale('log') labels = list(STATE_DESCRIPTIONS.values())[1:-2] if differences: labels = ['net newly ' + lb for lb in labels] plt.legend(labels) plt.set_xlabel('Days since first ' + str(self.params['geometry']['i']) + ' infections.')
def simulate(params, plt=None, plot_hourly=None, xlabel=None, callback=plot_callback): """ OU Pandemic simulation :param params: dict of dict as per pandemic.conventions :param plt: Handle to matplotlib plot :param plot_hourly: Bool Set False to speed up, True to see commuting :param xlabel: str Label for plot :param callback: Any function taking home, work, day, params, positions, status (e.g. for plotting, saving etc) :return: None Use the callback """ if plot_hourly is None: plot_hourly = params['geometry']['n'] < 50000 # Hack, remove # Initialize a city's geography and its denizens num, num_initially_infected = int(params['geometry']['n']), int( params['geometry']['i']) num_times_of_day = int(params['motion']['t']) precision = int(params['geometry']['p']) home, work = home_and_work_locations(geometry_params=params['geometry'], num=num) positions = nudge(home, w=0.05 * params['motion']['w']) status = np.random.permutation([INFECTED] * num_initially_infected + [VULNERABLE] * (num - num_initially_infected)) time_step = 1.0 / num_times_of_day # Population drifts to work and back, incurring viral load based on proximity to others who are infected day = 0 while any(s in [INFECTED] for s in status): day = day + 1 for step_no, day_fraction in enumerate(times_of_day(num_times_of_day)): stationary = [s in [DECEASED, POSITIVE] for s in status] attractors = destinations(status, day_fraction, home, work) positions = evolve_positions(positions=positions, motion_params=params['motion'], attractors=attractors, time_step=time_step, stationary=stationary) exposed = newly_exposed(positions=positions, status=status, precision=precision) status = contact_progression(status=status, health_params=params['health'], exposed=exposed) status = individual_progression(status, health_params=params['health'], day_fraction=time_step) if callback: callback(day=day, day_fraction=day_fraction, home=home, work=work, positions=positions, status=status, params=params, step_no=step_no, plot_hourly=plot_hourly, plt=plt) pprint(Counter([list(STATE_DESCRIPTIONS.values())[s] for s in status]))
# Get all valid parameter keys that have at least 150 days all_params = set() all_keys = set() ddata = list() for s, v in data.items(): i = int(s) vdata = [v_ / 800000 for v_ in json.loads(v)] all_keys.add(i) params_as_int = i % PARAMS_SCALE elapsed = float(s[:8]) / 10000 record = { 'key': i, 'params': params_as_int, 'elapsed': elapsed, 'reverse_key': params_as_int * 1000 + elapsed } for name, val in zip(STATE_DESCRIPTIONS.values(), vdata): record.update({name: val}) ddata.append(record) sdata = sorted(ddata, key=lambda x: x['reverse_key']) df = pd.DataFrame.from_records(sdata) g = df.groupby(by='params').count().sort_values(by='key') valid = list(g[g['key'] > 150].index.values) print(len(valid)) valid_row = [k in valid for k in df['params'].values] df1 = df.loc[valid_row, :] df1.sort_values(by=['params', 'elapsed'], inplace=True) df1.drop(columns=['key', 'params', 'elapsed', 'reverse_key'], inplace=True) df1.to_csv('dump.csv')