def format_plot_3(plt_3: Axes, x_vals: List[int], state_info_list: List[StateInfo]) -> BarContainer: """Adjust all properties of plot 3 to make it look nice. Add the x & y ticks, format those ticks, set the title, and place the text on the plot for the priority num plot. Parameters ---------- plt_3 : `Axes` The object that describes the graph x_vals : `List[int]` The list of ints that shows the states' position's state_info_list : `List[StateInfo]` Continually updated list of state calculation info Returns ------- `BarContainer` The objects describing the plotted bars """ state_names = extract_state_names(state_info_list) priority_list = extract_priority(state_info_list) plt_3_bars: BarContainer = plt_3.bar(x_vals, priority_list, align="center", color="g") plt_3.set_xticks(x_vals) plt_3.set_xticklabels(state_names, rotation="vertical") y_formatter: FuncFormatter = FuncFormatter(comma_format_int()) plt_3.set_ylabel("Priority value") plt_3.set_yscale("log") plt_3.get_yaxis().set_major_formatter(y_formatter) plt_3.text(0.3, 0.9, "Highlighted, is the state with the highest priority value", transform=plt_3.transAxes) plt_3.grid(axis="y", which="major", lw=2) plt_3.grid(axis="y", which="minor", lw=0.75) plt_3.grid(axis="x", lw=0.75) plt_3.set_title("Priority values per state") return plt_3_bars
def format_plot_2(plt_2: Axes, x_vals: List[int], state_info_list: List[StateInfo]) -> BarContainer: """Adjust all properties of plot 2 to make it look nice. Add the x & y ticks, format those ticks, set the title, and place the text on the plot for the number of reps plot. Parameters ---------- plt_2 : `Axes` The object that describes the graph x_vals : `List[int]` The list of ints that shows the states' position's state_info_list : `List[StateInfo]` Continually updated list of state calculation info Returns ------- `BarContainer` The objects describing the plotted bars """ state_names = extract_state_names(state_info_list) reps_list = extract_reps(state_info_list) plt_2_bars: BarContainer = plt_2.bar(x_vals, reps_list, align="center", color="r") plt_2.set_xticks(x_vals) plt_2.set_xticklabels(state_names, rotation="vertical") y_axis = plt_2.get_yaxis() minor_loc = MultipleLocator(5) y_axis.set_minor_locator(minor_loc) plt_2.set_ylabel("Representatives") plt_2.set_ylim(top=60, bottom=0) plt_2.grid(axis="y", which="major", lw=2) plt_2.grid(axis="y", which="minor", lw=0.75) plt_2.grid(axis="x", lw=0.75) plt_2.set_title("Representatives per state") return plt_2_bars
def format_plot_1(plt_1: Axes, x_vals: List[int], state_info_list: List[StateInfo]) -> PlotProps: """Adjust all properties of plot 1 to make it look nice. Add the x & y ticks, format those ticks, set the title, draw the mean line, and place the text on the plot for the pop_per_rep plot. Parameters ---------- plt_1 : `Axes` The object that describes the graph x_vals : `List[int]` The list of ints that shows the states' positions state_info_list : `List[StateInfo]` Continually updated list of state calculation info Returns ------- `PlotProps` A tuple of the plotted bars, text, and line objects """ state_names = extract_state_names(state_info_list) pop_per_rep_list = extract_pop_per_rep(state_info_list) plt_1_bars: BarContainer = plt_1.bar(x_vals, pop_per_rep_list, align="center") plt_1.set_xticks(x_vals) plt_1.set_xticklabels(state_names, rotation="vertical") y_formatter = FuncFormatter(comma_format_int()) plt_1.set_ylabel("People/Representative") plt_1.set_yscale("log") plt_1.get_yaxis().set_major_formatter(y_formatter) plt_1.set_title("People per representative per state") plt_1.grid(axis="y", which="major", lw=2) plt_1.grid(axis="y", which="minor", lw=0.75) plt_1.grid(axis="x", lw=0.75) mean_pop_per_seat: float = np.mean(pop_per_rep_list) std_dev_pop_per_seat: float = np.std(pop_per_rep_list) range_pop_per_seat: float = max(pop_per_rep_list) - min(pop_per_rep_list) geo_mean_pop_per_seat: float = geometric_mean(pop_per_rep_list) res_dict: PlotTextDict = {} res_dict["seat_txt"] = plt_1.text(0.25, 0.75, f"Seat# 1", transform=plt_1.transAxes) res_dict["state_txt"] = plt_1.text(0.15, 0.85, "State: ", transform=plt_1.transAxes) res_dict["mean_txt"] = plt_1.text(0.45, 0.75, f"Mean: {mean_pop_per_seat:,.2f}", transform=plt_1.transAxes) res_dict["std_dev_txt"] = plt_1.text( 0.35, 0.85, f"Std. Dev. {std_dev_pop_per_seat:,.2f}", transform=plt_1.transAxes) res_dict["range_txt"] = plt_1.text(0.70, 0.75, f"Range: {range_pop_per_seat:,.2f}", transform=plt_1.transAxes) res_dict["geo_mean_txt"] = plt_1.text( 0.6, 0.85, f"Geo. Mean: {geo_mean_pop_per_seat:,.2f}", transform=plt_1.transAxes) mean_line: Line2D = plt_1.axhline(y=mean_pop_per_seat, xmin=0.0, xmax=1.0, color="r") return (plt_1_bars, mean_line, res_dict)
def update(frameNum: int, img: mltimg.AxesImage, grid: np.ndarray, N: int, ax: mltax.Axes, G: int): newGrid = grid.copy() visited = np.zeros(N * N).reshape(N, N) counters = np.zeros(len(BEINGS)) reported = [] global FRAME if frameNum == 1: print("SUCCESS Simulation begins.") # implementation of the rules of Life for i in range(N): for j in range(N): rareCase = False myNeighbours = checkNeighbours(i, j, grid) me = int(grid[i][j]) if myNeighbours == 0: rareCase = True if me != 0 and myNeighbours < 2: # underpopulation newGrid[i][j] = 0 if me != 0 and (myNeighbours == 2 or myNeighbours == 3): # next generation newGrid[i][j] = 255 if me != 0 and myNeighbours > 3: # overpopulation newGrid[i][j] = 0 if me != 255 and myNeighbours == 3: # reproduction newGrid[i][j] = 255 # count Life patterns if not checked already if int(visited[i][j]) == 0: res, visited = countLife(i, j, grid, visited, rareCase) # if something detected, count it if len(res) > 0: reported.append(res) counters[int(res[0])] += 1 global TOTAL_COUNTERS TOTAL_COUNTERS[int(res[0])] += 1 # update total counters for seeds and others num, visited = countOthers(grid, visited) global TOTAL_OTHERS TOTAL_OTHERS += num global TOTAL_LIVES TOTAL_LIVES += len(reported) # report the count at every frame handleReport("------ Generation {0} ------\n".format(FRAME)) handleReport("Total Life Beings: {0}\n".format(len(reported))) handleReport("Total Other Beings: {0}\n".format(num)) handleReport("+++++++++++++++++++++++++++\n") for i in range(len(BEINGS)): handleReport("{n}: {v}\n".format(n=BEINGS_STR[i], v=int(counters[i]))) handleReport("+++++++++++++++++++++++++++\n") for j in range(len(reported)): handleReport("{i}. {n} at {y}, {x}\n".format( i=j + 1, n=BEINGS_STR[reported[j][0]], y=reported[j][1], x=reported[j][2])) # at last, calculate percentage of appearance if frameNum == (G - 1): handleReport("======= Incidence % =======\n") if TOTAL_LIVES == 0 and TOTAL_OTHERS == 0: TOTAL_LIVES = 1 # to avoid div by zero for i in range(len(BEINGS)): handleReport("{n}: {v} %\n".format( n=BEINGS_STR[i], v=round( (TOTAL_COUNTERS[i] / (TOTAL_LIVES + TOTAL_OTHERS)) * 100.0, 2))) handleReport("{n}: {v} %\n".format( n="others", v=round((TOTAL_OTHERS / (TOTAL_LIVES + TOTAL_OTHERS)) * 100.0, 2))) handleReport("", True) print("SUCCESS Simulation Report is now available.") # update data ax.set_title("Conway's Game of Life\nGeneration = {0}".format(frameNum + 1)) img.set_data(newGrid) img.set_cmap('binary') grid[:] = newGrid[:] FRAME += 1 return img,