import json from collections import defaultdict from typing import List, Tuple import matplotlib.pyplot as plt import os import numpy as np from scipy.interpolate import interp1d import networkx as nx import itertools from analysis.analyzers import Store, BiogamesStore, SimulationOrderAnalyzer from analysis.util.meta_temp import CONFIG_NAMES from . import Render from .. import Result, SimulationRoundsAnalyzer, BoardDurationAnalyzer, ActivityMapper def add_edge(graph, src, dest): if graph.has_edge(src, dest): weight = graph.get_edge_data(src, dest)['weight'] + 1 else: weight = 1 graph.add_edge(tuple(src), tuple(dest), weight=weight) def pairs(iterable): a, b = itertools.tee(iterable) next(b, None) return zip(a, b) def __plot_or_show(name=None): if name: plt.savefig(name) else: plt.show() plt.cla() plt.clf() plt.close() def plot(src_data: List[Tuple[str, List[int]]], ylabel="simulation rounds", title="simulation retries", rotation='vertical', name=None): names, datas = list(zip(*src_data)) # plt.boxplot(datas, labels=names, showfliers=False, showmeans=True, meanline=True) rand = np.random.rand(len(datas), len(datas[0])) plt.plot(datas + rand, linewidth=.2) plt.xticks(rotation=rotation) # plt.margins() plt.ylabel(ylabel) plt.title(title) __plot_or_show(name) def graph_plot(src_data: List[Tuple[str, List[int]]], ylabel="simulation rounds", title="sequential simulation retries", rotation='vertical', name=None): config_name = CONFIG_NAMES[name] if name in CONFIG_NAMES else "---" counts_per_group = [sum(i) for i in src_data] label = "{}: n={n}; # of sim runs: ⌀={avg:.2f}, median={median}".format( config_name, n=len(src_data), avg=np.mean(counts_per_group), median=np.median(counts_per_group) ) print(config_name) name = "plots/{}.png".format(name) g = nx.Graph() for group in src_data: for i in pairs(enumerate(group)): add_edge(g, i[0], i[1]) positions = {} for node in g.nodes(): positions[node] = node widths = [x[2] / 10.0 for x in g.edges.data('weight')] print(max(widths)) nx.draw_networkx_edges(g, positions, width=widths) # rand = np.random.rand(len(datas),len(datas[0])) # plt.plot(datas+rand, linewidth=.2) plt.xticks(rotation=rotation) # plt.margins() plt.ylabel(ylabel) plt.title(title) plt.figtext(0.5, 0.13, label, ha="center") __plot_or_show(name) def graph_fit(src_data, deg=5, name=None): plt.title("polyfit(x,y,deg=" + str(deg) + ")") for i in src_data: # plt.plot(i) count = len(i) xp = np.linspace(0, count - 1, num=count, endpoint=True) # fit = np.poly1d(np.polyfit(range(len(i)), i, deg=deg)) # plt.plot(xp, fit(xp), linewidth=0.1) xnew = np.linspace(0, count - 1, num=count * 20, endpoint=True) f = interp1d(xp, i, kind='quadratic') plt.plot(range(count), i, '.', markersize=1) plt.plot(xnew, f(xnew), linewidth=0.2) __plot_or_show(name) class SimulationRoundsRender(Render): def render(self, results: List[Result], name=None): data = defaultdict(list) for result in self.filter(results): get = result.get() for key in get: data[key].append(get[key]) data_tuples = [(key, data[key]) for key in sorted(data)] data_tuples = sorted(data_tuples, key=lambda x: sum(x[1])) plot(data_tuples) result_types = [SimulationRoundsAnalyzer] class BoardDurationHistRender(Render): result_types = [BoardDurationAnalyzer] def render(self, results: List[Result], name=None): data = [] for result in self.filter(results): session = result.get() _data = [] for board in session: if "active" in board: _data.append(board["active"]) else: _data.append(0) data.append(_data) n, bins, patches = plt.hist(data, log=True) plt.show() class BoardDurationBoxRender(Render): result_types = [BoardDurationAnalyzer] def render(self, results: List[Result], name=None) -> [str]: data = defaultdict(list) for result in self.filter(results): for board in result.get(): duration = board['active'] if 'active' in board else 0 data[board['id']].append(duration) data_tuples = [(key, data[key]) for key in sorted(data)] data_tuples = sorted(data_tuples, key=lambda x: sum(x[1])) plot(data_tuples, name=name) return [name] class ActivityMapperRender(Render): result_types = [ActivityMapper] def render(self, results: List[Result], name=None): print(os.getcwd()) files = [] for result in self.filter(results): data = result.get() path = os.path.join("/tmp", data['instance'] + "_" + str(name) + ".json") with open(path, "w") as out: json.dump(data, out, indent=1) files.append(path) return files class StoreRender(Render): result_types = [Store, BiogamesStore] def render(self, results: List[Result], name=None): for result in self.filter(results): with open(os.path.join("static", "progress", "data", "fooo"), "w") as out: json.dump(result.get(), out, indent=1) class SimulationOrderRender(Render): def render(self, results: List[Result], name=None): data = defaultdict(list) for result in self.filter(results): get = result.get() for i, value in enumerate(get): data[i].append(value) # data_tuples = [(key, data[key]) for key in sorted(data)] # data_tuples = sorted(data_tuples, key=lambda x: sum(x[1])) # plot(enumerate([r.get() for r in self.filter(results)])) plot(list(data.items()), ylabel="simulation retries", title="sequential simulation retries", rotation=None) result_types = [SimulationOrderAnalyzer] class SimulationGroupRender(Render): def render(self, results: List[Result], name=None): # data = [r.get() for r in self.filter(results)] data = [] for r in self.filter(results): raw = r.get() if len(raw) < 6: raw = [0] + raw data.append(raw) print(name, len(data)) # graph_fit(list(data), name=name) graph_plot(list(data), ylabel="simulation retries", title="sequential simulation retries", rotation=None, name=name) result_types = [SimulationOrderAnalyzer]