Spaces:
Build error
Build error
| import matplotlib.pyplot as plt | |
| import random | |
| import numpy as np | |
| import pandas as pd | |
| from matplotlib.lines import Line2D | |
| #single_random_walk takes a single particle and plots its trajectory on the axis passed to it | |
| def single_random_walk(iters, agent_number, ax, step_size = 1, random_seed = None): | |
| if random_seed: | |
| random.seed(random_seed) | |
| iters = int(iters) #Because for some reason, the input from Gradio input components is in float | |
| directions = ['east', 'north', 'west', 'south'] | |
| start_point = [0, 0] | |
| def distance_from_start(final_coord, start_coord, round_to=2): | |
| return round(np.sqrt((final_coord[0] - start_coord[0])**2 + (final_coord[1] - start_coord[1])**2), round_to) | |
| def step_addition(old_coord, step): | |
| return [sum(x) for x in zip(old_coord, step)] | |
| def step_determination(): | |
| direction = random.choice(directions) | |
| if direction == 'east': | |
| return [1*step_size, 0] | |
| elif direction == 'west': | |
| return [-1*step_size, 0] | |
| elif direction == 'north': | |
| return [0, 1*step_size] | |
| elif direction == 'south': | |
| return [0, -1*step_size] | |
| coordinate_list = [start_point] | |
| for _ in range(iters): #Key part that decides the trajectory of the agent | |
| new_step = step_determination() | |
| new_coordinate = step_addition(coordinate_list[-1], new_step) | |
| coordinate_list.append(new_coordinate) | |
| x = [i[0] for i in coordinate_list] | |
| y = [i[1] for i in coordinate_list] | |
| df = pd.DataFrame({'x':x,'y':y}) | |
| #This to determine the markersize. This is is only a makeshift solution. | |
| base_marker_size = 10 | |
| markersize = base_marker_size / np.sqrt(iters) | |
| #Plot on the axis passed, do not make a new figure. | |
| plot = ax.plot(x, y, marker='o', markersize=markersize, linestyle='None', alpha=0.5, label = 'Agent {i}'.format(i=agent_number+1)) | |
| color = plot[0].get_color() #Get the color so that we can add label with proper colors later | |
| ax.plot(x[-1], y[-1], marker='o', markersize=5, color = 'black') | |
| ax.text(x[-1], y[-1], 'End {i}'.format(i=agent_number+1), color = 'black', alpha=1.0) | |
| return ax, df, color | |
| #multi_agent_walk iteratively calls the single_random_walk function to plot different trajectories on the same axis. | |
| def multi_agent_walk(agent_count, iters, step_size = 1, random_seed = None): | |
| assert agent_count >= 1, "Number of agents must be >= than 1" | |
| agent_count = int(agent_count) | |
| iters = int(iters) | |
| def displacement_calc(df): | |
| x1,y1 = df.iloc[0] | |
| x2,y2 = df.iloc[-1] | |
| return np.round(np.sqrt((x2-x1)**2 + (y2-y1)**2),1) | |
| if random_seed is None: | |
| random_seed = random.randint(0,1000000) | |
| random_seed = int(random_seed) | |
| assert type(random_seed) == int, "Random seed must be an integer" | |
| #Generates a list of random seeds for each agent | |
| random.seed(random_seed) | |
| random_numbers = [random.randint(0,100000) for _ in range(agent_count)] | |
| fig, ax = plt.subplots(figsize=(8,8)) | |
| color_list = [] | |
| for i in range(agent_count): | |
| if i == 0: | |
| ax, df, color = single_random_walk(iters=iters, ax=ax, step_size=step_size, agent_number=i, random_seed=random_numbers[i]) | |
| color_list.append(color) | |
| else: | |
| ax, df_new, color = single_random_walk(iters=iters, ax=ax, step_size=step_size, agent_number=i, random_seed=random_numbers[i]) | |
| df = pd.concat([df,df_new], axis=1) | |
| x_columns = [f'x{i}' for i in range(1, i+2)] | |
| y_columns = [f'y{i}' for i in range(1, i+2)] | |
| new_column_names = [val for pair in zip(x_columns, y_columns) for val in pair] | |
| df.columns = new_column_names | |
| color_list.append(color) | |
| ax.plot(0,0, marker='X', markersize=8, color='black') | |
| ax.text(0, 0, 'Start (0,0)') | |
| plt.grid() | |
| plt.title('Random 2D Walk with {} agents\n #Steps = {}, Step size = {}, random seed = {}\nAll agents start from the origin'.format(agent_count, iters, step_size, random_seed)) | |
| displacement = [displacement_calc(df.iloc[:,[i,i+1]]) for i in range(0,agent_count*2,2)] | |
| end_point = [(df.iloc[-1,i]) for i in range(0,agent_count*2,2)] | |
| end_point = [(df.iloc[-1,i], df.iloc[-1,i+1]) for i in range(0,agent_count*2,2)] | |
| agent_number = [i+1 for i in range(agent_count)] | |
| legend_df = pd.DataFrame({'#':agent_number, 'dis.':displacement, 'End Point':end_point, }) | |
| info_box = legend_df.to_string(index=False) | |
| ax.text(0.01, 0.99, info_box, | |
| transform=ax.transAxes, | |
| verticalalignment='top', | |
| bbox=dict(boxstyle='round', facecolor='white', alpha=0.5) | |
| ) | |
| lines = [] | |
| for i in range(len(color_list)): | |
| lines.append(Line2D([0], [0], color=color_list[i], lw=9, linestyle=':')) | |
| labels = [f'Agent {i+1}' for i in range(len(color_list))] | |
| plt.legend(lines, labels, | |
| loc='best', | |
| handlelength=1.01, | |
| handletextpad=0.21, | |
| fancybox=True, | |
| fontsize=10, | |
| ) | |
| fig.canvas.draw() | |
| image_array = np.array(fig.canvas.renderer.buffer_rgba()) | |
| csv_file = "2d_random_walk_coordinates.csv" | |
| df.to_csv(csv_file, index=False) | |
| try: | |
| return image_array, csv_file | |
| except: | |
| return image_array, None | |
| # _, df = multi_agent_walk(agent_count=9, iters=1e5, step_size=1, random_seed=123); | |