def trace(graph: pgv.AGraph, start: str, end: str) -> pgv.AGraph: nxgraph = nx.nx_agraph.from_agraph(graph) assert(start in nxgraph and end in nxgraph) shortest = nx.shortest_path(nxgraph, start, end) shgraph = pgv.AGraph(directed=True,overlap=False,rankdir='LR') for e in range(len(shortest)-1): label = graph.get_edge(shortest[e], shortest[e+1]).attr['label'] shgraph.add_edge(shortest[e], shortest[e+1], label=label) for n in shgraph.nodes_iter(): n.attr['label'] = graph.get_node(n).attr['label'] n.attr['style'] = graph.get_node(n).attr['style'] n.attr['fillcolor'] = graph.get_node(n).attr['fillcolor'] return shgraph
def build_graph(score): corpus= create_corpus(score) calc_tf_idf(corpus, log_tf, log_idf) #corpus= group_corpus(corpus, log_tf, log_idf) g= AGraph(strict=False) for i, d1 in enumerate(corpus): d1_name= str(d1) edges= [(d2, d2.similarity(d1)) for d2 in corpus[i+1:]] edges.sort(key=lambda x:x[1], reverse=True) edges= edges[:5] for d2, weight in edges: d2_name= str(d2) g.add_edge(d1_name, d2_name) e= g.get_edge(d1_name, d2_name) e.attr['label']= str(weight)[:5] #import ipdb;ipdb.set_trace() return g
def draw_relations(self, relations, fname): def get_node_name(n): return n.__name__ g= AGraph(directed=True) for n in relations: n_name= get_node_name(n) g.add_node(n_name) for relation in chain(*relations.values()): n1_name= get_node_name(relation.object1) n2_name= get_node_name(relation.object2) g.add_edge(n1_name, n2_name) e= g.get_edge(n1_name, n2_name) relation.set_edge_attributes(e) for n in g.nodes(): n.attr['shape']= 'box' g.draw(fname, prog='dot', args='-Grankdir=TB')
class DotGraphSearchProblem(Problem): def __init__(self, filename): self.G = AGraph(filename) xs = [(nodo, nodo.attr.get("initial", None)) for nodo in self.G.iternodes()] xs = [x for x in xs if x[1]] if len(xs) == 0: raise BadInputGraph("Missing 'initial' node") elif len(xs) > 1: raise BadInputGraph("Cannot have two initial nodes") if not any(nodo.attr.get("goal", None) for nodo in self.G.iternodes()): raise BadInputGraph("Missing a goal state '[goal=\"1\"]'") super(DotGraphSearchProblem, self).__init__(xs[0][0]) self.initial_state.attr["shape"] = "doublecircle" for node in self.G.iternodes(): if self.is_goal(node): node.attr["shape"] = "hexagon" node.attr["color"] = "blue" self.seen = set() self.visit(self.initial_state) for edge in self.G.iteredges(): edge.attr["style"] = "dotted" x = edge.attr.get("weight", None) if x: x = int(x) else: x = 1 edge.attr["weight"] = x edge.attr["label"] = x def actions(self, state): assert state in self.G if self.G.is_directed(): return self.G.itersucc(state) else: assert self.G.is_undirected() return self.G.iterneighbors(state) def result(self, state, action): assert state in self.G and action in self.G self.visit(state) return action def cost(self, state1, action, state2): assert state1 in self.G and action in self.G and action == state2 x = self.G.get_edge(state1, state2).attr["weight"] if float(x) == int(x): return int(x) else: return float(x) def visit(self, state): if state in self.seen: return self.seen.add(state) attr = self.G.get_node(state).attr attr["color"] = "firebrick" def is_goal(self, state): return bool(state.attr.get("goal", False)) def value(self, state): assert state in self.G value = self.G.get_node(state).attr.get("value", None) if not value: return 0 return float(value)
class GraphGeneratingReporter(BaseReporter): def __init__(self): self.evolution = [] # List[str] self._evaluating = None # Dict[Candidate, Set[Requirement]] self._dependencies = defaultdict(set) # Dict[Candidate.name, Counter[Requirement]] self._active_requirements = defaultdict(Counter) self._node_names = {} self._counter = count() self.graph = AGraph( directed=True, rankdir="LR", labelloc="top", labeljust="center", nodesep="0", concentrate="true", ) self.graph.add_node("root", label=":root:", shape="Mdiamond") self._node_names[self._key(None)] = "root" del self.graph.node_attr["label"] self.graph.edge_attr.update({ "arrowhead": "empty", "style": "dashed", "color": "#808080" }) # # Internal Graph-handling API # def _prepare_node(self, obj): cls = obj.__class__.__name__ n = next(self._counter) node_name = f"{cls}_{n}" self._node_names[self._key(obj)] = node_name return node_name def _key(self, obj): if obj is None: return None return ( obj.__class__.__name__, repr(obj), ) def _get_subgraph(self, name, *, must_exist_already=True): name = canonicalize_name(name) c_name = f"cluster_{name}" subgraph = self.graph.get_subgraph(c_name) if subgraph is None: if must_exist_already: existing = [s.name for s in self.graph.subgraphs_iter()] raise RuntimeError( f"Graph for {name} not found. Existing: {existing}") else: subgraph = self.graph.add_subgraph(name=c_name, label=name) return subgraph def _add_candidate(self, candidate): if candidate is None: return if self._key(candidate) in self._node_names: return node_name = self._prepare_node(candidate) # A candidate is only seen after a requirement with the same name. subgraph = self._get_subgraph(candidate.name, must_exist_already=True) subgraph.add_node(node_name, label=candidate.version, shape="box") def _add_requirement(self, req): if self._key(req) in self._node_names: return name = self._prepare_node(req) subgraph = self._get_subgraph(req.name, must_exist_already=False) subgraph.add_node(name, label=str(req.specifier) or "*", shape="cds") def _ensure_edge(self, from_, *, to, **attrs): from_node = self._node_names[self._key(from_)] to_node = self._node_names[self._key(to)] try: existing = self.graph.get_edge(from_node, to_node) except KeyError: attrs.update(headport="w", tailport="e") self.graph.add_edge(from_node, to_node, **attrs) else: existing.attr.update(attrs) def _get_node_for(self, obj): node_name = self._node_names[self._key(obj)] node = self.graph.get_node(node_name) assert node is not None return node_name, node def _track_evaluating(self, candidate): if self._evaluating != candidate: if self._evaluating is not None: self.backtracking(self._evaluating, internal=True) self.evolution.append(self.graph.to_string()) self._evaluating = candidate # # Public reporter API # def starting(self): print("starting(self)") def starting_round(self, index): print(f"starting_round(self, {index})") # self.graph.graph_attr["label"] = f"Round {index}" self.evolution.append(self.graph.to_string()) def ending_round(self, index, state): print(f"ending_round(self, {index}, state)") def ending(self, state): print("ending(self, state)") def adding_requirement(self, req, parent): print(f"adding_requirement(self, {req!r}, {parent!r})") self._track_evaluating(parent) self._add_candidate(parent) self._add_requirement(req) self._ensure_edge(parent, to=req) self._active_requirements[canonicalize_name(req.name)][req] += 1 self._dependencies[parent].add(req) if parent is None: return # We're seeing the parent candidate (which is being "evaluated"), so # color all "active" requirements pointing to the it. # TODO: How does this interact with revisited candidates? for parent_req in self._active_requirements[canonicalize_name( parent.name)]: self._ensure_edge(parent_req, to=parent, color="#80CC80") def backtracking(self, candidate, internal=False): print(f"backtracking(self, {candidate!r}, internal={internal})") self._track_evaluating(candidate) self._evaluating = None # Update the graph! node_name, node = self._get_node_for(candidate) node.attr.update(shape="signature", color="red") for edge in self.graph.out_edges_iter([node_name]): edge.attr.update(style="dotted", arrowhead="vee", color="#FF9999") _, to = edge to.attr.update(color="black") for edge in self.graph.in_edges_iter([node_name]): edge.attr.update(style="dotted", color="#808080") # Trim "active" requirements to remove anything not relevant now. for requirement in self._dependencies[candidate]: active = self._active_requirements[canonicalize_name( requirement.name)] active[requirement] -= 1 if not active[requirement]: del active[requirement] def pinning(self, candidate): print(f"pinning(self, {candidate!r})") assert self._evaluating == candidate or self._evaluating is None self._evaluating = None self._add_candidate(candidate) # Update the graph! node_name, node = self._get_node_for(candidate) node.attr.update(color="#80CC80") # Requirement -> Candidate edges, from this candidate. for req in self._active_requirements[canonicalize_name( candidate.name)]: self._ensure_edge(req, to=candidate, arrowhead="vee", color="#80CC80") # Candidate -> Requirement edges, from this candidate. for edge in self.graph.out_edges_iter([node_name]): edge.attr.update(style="solid", arrowhead="vee", color="#80CC80") _, to = edge to.attr.update(color="#80C080")
def dot_layout(cy_elements, edge_labels=False, subgraph_boxes=False, node_gt=None): """ Get a CyElements object and augment it (in-place) with positions, widths, heights, and spline data from a dot based layout. edge_labels is true if labels should appear on edges subgraph_boxes is true if boxes should be drawn around subgraphs Returns the object. """ elements = cy_elements.elements # g = AGraph(directed=True, strict=False) g = AGraph(directed=True, strict=False, forcelabels=True) # make transitive relations appear top to bottom elements = list(elements) nodes_by_id = dict((e["data"]["id"], e) for e in elements if e["group"] == "nodes") order = [ (nodes_by_id[e["data"]["source"]], nodes_by_id[e["data"]["target"]]) for e in elements if e["group"] == "edges" and "transitive" in e["data"] and e["data"]["transitive"] ] elements = topological_sort(elements, order, lambda e: e["data"]["id"]) # get the node id's and stable sort them by cluster # the idea here is to convert the graph into a dag by sorting # the nodes, then reversing the back edges. In particular, we try to make # all the edges between two clusters go in the same direction so clustering # doesn't result in horizontal edges, which dot renders badly. sorted_nodes = [e["data"]["id"] for e in elements if e["group"] == "nodes"] sorted_nodes = sorted(enumerate(sorted_nodes), key=lambda x: (nodes_by_id[x[1]]["data"]["cluster"], x[0])) sorted_nodes = [y for idx, y in sorted_nodes] node_key = dict((id, idx) for idx, id in enumerate(sorted_nodes)) if node_gt is None: node_gt = lambda X, y: False else: node_gt = lambda x, y: node_key[x] > node_key[y] # add nodes to the graph for e in elements: if e["group"] == "nodes" and e["classes"] != "non_existing": g.add_node(e["data"]["id"], label=e["data"]["label"].replace("\n", "\\n")) # TODO: remove this, it's specific to leader_demo weight = {"reach": 10, "le": 10, "id": 1} constraint = {"pending": False} # add edges to the graph for e in elements: if e["group"] == "edges": # kwargs = {'weight': weight.get(e["data"]["obj"], 0)}, kwargs = {"label": e["data"]["label"]} if edge_labels else {} if node_gt(e["data"]["source"], e["data"]["target"]): g.add_edge( e["data"]["target"], e["data"]["source"], e["data"]["id"], dir="back", **kwargs # constraint=constraint.get(e["data"]["obj"], True), ) else: g.add_edge( e["data"]["source"], e["data"]["target"], e["data"]["id"], **kwargs # constraint=constraint.get(e["data"]["obj"], True), ) # add clusters clusters = defaultdict(list) for e in elements: if e["group"] == "nodes" and e["data"]["cluster"] is not None and e["classes"] != "non_existing": clusters[e["data"]["cluster"]].append(e["data"]["id"]) for i, k in enumerate(sorted(clusters.keys())): g.add_subgraph(name="cluster_{}".format(i), nbunch=clusters[k], rank="min") # now get positions, heights, widths, and bsplines g.layout(prog="dot") # get the y origin. we want the top left of the graph to be a # fixed coordinate (hopefully (0,0)) so the graph doesn't jump when # its height changes. Unfortunately, pygraphviz has a bug a gives # the wrong bbox, so we compute the max y coord. # bbox = pygraphviz.graphviz.agget(g.handle,'bb') global y_origin y_origin = 0.0 for n in g.nodes(): top = float(n.attr["pos"].split(",")[1]) + float(n.attr["height"]) / 2 if top > y_origin: y_origin = top if subgraph_boxes: for sg in g.subgraphs(): top = float(sg.graph_attr["bb"].split(",")[3]) if top > y_origin: y_origin = top for e in elements: if e["group"] == "nodes" and e["classes"] != "non_existing": attr = g.get_node(e["data"]["id"]).attr e["position"] = _to_position(attr["pos"]) e["data"]["width"] = 72 * float(attr["width"]) e["data"]["height"] = 72 * float(attr["height"]) elif e["group"] == "edges": if node_gt(e["data"]["source"], e["data"]["target"]): attr = g.get_edge(e["data"]["target"], e["data"]["source"], e["data"]["id"]).attr pos = attr["pos"] pe = pos.split() ppe = pe[1:] ppe.reverse() pos = " ".join([pe[0].replace("s", "e")] + ppe) else: attr = g.get_edge(e["data"]["source"], e["data"]["target"], e["data"]["id"]).attr pos = attr["pos"] e["data"].update(_to_edge_position(pos)) if edge_labels and e["data"]["label"] != "": e["data"]["lp"] = _to_position(attr["lp"]) # g.draw('g.png') if subgraph_boxes: for sg in g.subgraphs(): box = cy_elements.add_shape(sg.name, classes="subgraphs") coords = _to_coord_list(sg.graph_attr["bb"]) box["data"]["coords"] = coords return cy_elements
def dot_layout(cy_elements): """ Get a CyElements object and augment it (in-place) with positions, widths, heights, and spline data from a dot based layout. Returns the object. """ elements = cy_elements.elements g = AGraph(directed=True, strict=False) # make transitive relations appear top to bottom # TODO: make this not specific to leader example elements = list(elements) nodes_by_id = dict( (e["data"]["id"], e) for e in elements if e["group"] == "nodes") order = [(nodes_by_id[e["data"]["source"]], nodes_by_id[e["data"]["target"]]) for e in elements if e["group"] == "edges" and e["data"]["obj"] in ('reach', 'le')] elements = topological_sort(elements, order, lambda e: e["data"]["id"]) # add nodes to the graph for e in elements: if e["group"] == "nodes": g.add_node(e["data"]["id"], label=e["data"]["label"].replace('\n', '\\n')) # TODO: remove this, it's specific to leader_demo weight = { 'reach': 10, 'le': 10, 'id': 1, } constraint = { 'pending': False, } # add edges to the graph for e in elements: if e["group"] == "edges": g.add_edge( e["data"]["source"], e["data"]["target"], e["data"]["id"], weight=weight.get(e["data"]["obj"], 0), #constraint=constraint.get(e["data"]["obj"], True), ) # add clusters clusters = defaultdict(list) for e in elements: if e["group"] == "nodes" and e["data"]["cluster"] is not None: clusters[e["data"]["cluster"]].append(e["data"]["id"]) for i, k in enumerate(sorted(clusters.keys())): g.add_subgraph( name='cluster_{}'.format(i), nbunch=clusters[k], ) # now get positions, heights, widths, and bsplines g.layout(prog='dot') for e in elements: if e["group"] == "nodes": attr = g.get_node(e["data"]["id"]).attr e["position"] = _to_position(attr['pos']) e["data"]["width"] = 72 * float(attr['width']) e["data"]["height"] = 72 * float(attr['height']) elif e["group"] == "edges": attr = g.get_edge(e["data"]["source"], e["data"]["target"], e["data"]["id"]).attr e["data"].update(_to_edge_position(attr['pos'])) g.draw('g.png') return cy_elements
def main(): usage= 'usage: %prog [options] midis' parser= OptionParser(usage=usage) parser.add_option('--n-measures', dest='n_measures', default=1, type='int', help='if the partition algorithm is MEASURE, especifies the number of measures to take as a unit') parser.add_option('-o', dest='outfname', help='the output file') options, args= parser.parse_args(argv[1:]) if len(args) < 1: parser.error('not enaught args') outfname= options.outfname if outfname is None: parser.error('missing outfname') infnames= args[:] parser= MidiScoreParser() models= [] for infname in infnames: score= parser.parse(infname) if not score: import ipdb;ipdb.set_trace() # por que podria devolver None? ######### # AJUSTES DE PARSING notes= score.get_first_voice() notes= [n for n in notes if n.duration > 0] instr= score.notes_per_instrument.keys()[0] patch= instr.patch channel= instr.channel score.notes_per_instrument= {instr:notes} ######### interval_size= measure_interval_size(score, options.n_measures) algorithm= HarmonyHMM(interval_size, instrument=patch, channel=channel) algorithm.train(score) algorithm.create_model() models.append(algorithm.model) def sim(m1, m2): """ calcula H(m1|m2) """ from math import log ans= 0 for s1 in m2.state_transition: for s2, prob in m1.state_transition.get(s1, {}).iteritems(): ans+= m2.pi[s1]*prob*log(prob) return -ans from os import path def get_node_name(ticks): n_quarters= 0 while ticks >= score.divisions: ticks-= score.divisions n_quarters+= 1 if ticks > 0: f= Fraction(ticks, score.divisions) if n_quarters > 0: return "%s + %s" % (n_quarters, f) else: return repr(f) return "%s" % n_quarters for i, m in enumerate(models): m.pi= m.calc_stationationary_distr() from pygraphviz import AGraph from utils.fraction import Fraction g= AGraph(directed=True, strict=False) for n1, adj in m.state_transition.iteritems(): n1_name= get_node_name(n1) for n2, prob in adj.iteritems(): n2_name= get_node_name(n2) g.add_edge(n1_name, n2_name) e= g.get_edge(n1_name, n2_name) e.attr['label']= str(prob)[:5] model_fname= path.basename(infnames[i]).replace('mid', 'png') g.draw(model_fname, prog='dot', args='-Grankdir=LR') sims= defaultdict(dict) for i, m1 in enumerate(models): for j in xrange(i+1, len(models)): m2= models[j] sims[path.basename(infnames[i])][path.basename(infnames[j])]= sim(m1, m2) sims[path.basename(infnames[j])][path.basename(infnames[i])]= sim(m2, m1) import csv f= open(outfname, 'w') writer= csv.writer(f) head= sorted(sims) head.insert(0, "-") writer.writerow(head) for (k, row) in sorted(sims.iteritems(), key=lambda x:x[0]): row= sorted(row.iteritems(), key=lambda x:x[0]) row= [t[1] for t in row] row.insert(0, k) writer.writerow(row) f.close() return from pygraphviz import AGraph from utils.fraction import Fraction g= AGraph(directed=True, strict=False) for infname1, adj in sims.iteritems(): for infname2, sim in adj.iteritems(): if sim>0.2 and sim!=0: continue g.add_edge(infname1, infname2) e= g.get_edge(infname1, infname2) e.attr['label']= str(sim)[:5] g.draw(outfname, prog='dot')
def dot_layout(cy_elements, edge_labels=False, subgraph_boxes=False, node_gt=None): """ Get a CyElements object and augment it (in-place) with positions, widths, heights, and spline data from a dot based layout. edge_labels is true if labels should appear on edges subgraph_boxes is true if boxes should be drawn around subgraphs Returns the object. """ elements = cy_elements.elements # g = AGraph(directed=True, strict=False) g = AGraph(directed=True, strict=False, forcelabels=True) # make transitive relations appear top to bottom elements = list(elements) nodes_by_id = dict( (e["data"]["id"], e) for e in elements if e["group"] == "nodes") order = [(nodes_by_id[e["data"]["source"]], nodes_by_id[e["data"]["target"]]) for e in elements if e["group"] == "edges" and "transitive" in e["data"] and e["data"]["transitive"]] elements = topological_sort(elements, order, lambda e: e["data"]["id"]) # get the node id's and stable sort them by cluster # the idea here is to convert the graph into a dag by sorting # the nodes, then reversing the back edges. In particular, we try to make # all the edges between two clusters go in the same direction so clustering # doesn't result in horizontal edges, which dot renders badly. sorted_nodes = [e["data"]["id"] for e in elements if e["group"] == "nodes"] sorted_nodes = sorted(enumerate(sorted_nodes), key=lambda x: (nodes_by_id[x[1]]["data"]["cluster"], x[0])) sorted_nodes = [y for idx, y in sorted_nodes] node_key = dict((id, idx) for idx, id in enumerate(sorted_nodes)) if node_gt is None: node_gt = lambda X, y: False else: node_gt = lambda x, y: node_key[x] > node_key[y] # add nodes to the graph for e in elements: if e["group"] == "nodes" and e["classes"] != 'non_existing': g.add_node(e["data"]["id"], label=e["data"]["label"].replace('\n', '\\n')) # TODO: remove this, it's specific to leader_demo weight = { 'reach': 10, 'le': 10, 'id': 1, } constraint = { 'pending': False, } # add edges to the graph for e in elements: if e["group"] == "edges": # kwargs = {'weight': weight.get(e["data"]["obj"], 0)}, kwargs = {'label': e["data"]["label"]} if edge_labels else {} if node_gt(e["data"]["source"], e["data"]["target"]): g.add_edge(e["data"]["target"], e["data"]["source"], e["data"]["id"], dir='back', **kwargs #constraint=constraint.get(e["data"]["obj"], True), ) else: g.add_edge(e["data"]["source"], e["data"]["target"], e["data"]["id"], **kwargs #constraint=constraint.get(e["data"]["obj"], True), ) # add clusters clusters = defaultdict(list) for e in elements: if e["group"] == "nodes" and e["data"][ "cluster"] is not None and e["classes"] != 'non_existing': clusters[e["data"]["cluster"]].append(e["data"]["id"]) for i, k in enumerate(sorted(clusters.keys())): g.add_subgraph( name='cluster_{}'.format(i), nbunch=clusters[k], rank='min', ) # now get positions, heights, widths, and bsplines g.layout(prog='dot') # get the y origin. we want the top left of the graph to be a # fixed coordinate (hopefully (0,0)) so the graph doesn't jump when # its height changes. Unfortunately, pygraphviz has a bug a gives # the wrong bbox, so we compute the max y coord. # bbox = pygraphviz.graphviz.agget(g.handle,'bb') global y_origin y_origin = 0.0 for n in g.nodes(): top = float(n.attr['pos'].split(',')[1]) + float(n.attr['height']) / 2 if top > y_origin: y_origin = top if subgraph_boxes: for sg in g.subgraphs(): top = float(sg.graph_attr['bb'].split(',')[3]) if top > y_origin: y_origin = top for e in elements: if e["group"] == "nodes" and e["classes"] != 'non_existing': attr = g.get_node(e["data"]["id"]).attr e["position"] = _to_position(attr['pos']) e["data"]["width"] = 72 * float(attr['width']) e["data"]["height"] = 72 * float(attr['height']) elif e["group"] == "edges": if node_gt(e["data"]["source"], e["data"]["target"]): attr = g.get_edge(e["data"]["target"], e["data"]["source"], e["data"]["id"]).attr pos = attr['pos'] pe = pos.split() ppe = pe[1:] ppe.reverse() pos = ' '.join([pe[0].replace('s', 'e')] + ppe) else: attr = g.get_edge(e["data"]["source"], e["data"]["target"], e["data"]["id"]).attr pos = attr['pos'] e["data"].update(_to_edge_position(pos)) if edge_labels and e["data"]["label"] != '': e["data"]["lp"] = _to_position(attr['lp']) # g.draw('g.png') if subgraph_boxes: for sg in g.subgraphs(): box = cy_elements.add_shape(sg.name, classes='subgraphs') coords = _to_coord_list(sg.graph_attr['bb']) box["data"]["coords"] = coords return cy_elements
def recalculate(user): # remove old ranking RankedTeam.objects.filter(team__user = user).delete() for pic in RankingPicture.objects.all(): pic.image.delete() pic.delete() color_index = 0 team_graph = Graph() gvfull = AGraph(directed = True) for team in user.teams.all(): gvfull.add_node(asciiname(team), label = team.name) team_graph.add_node(team) for game in Game.objects.filter(team_1__user = user, team_2__user = user): team_graph.add_edge(game.winner(), game.loser(), game.jugg_diff()) for source, dest, weight in team_graph.edges(): gvfull.add_edge(asciiname(source), asciiname(dest), label = str(weight)) current_place = 1 gvcircles = AGraph(directed = True) gvtiebreaker = AGraph(directed = True) for place in team_graph.topological_sort(): place_list = [] relevant_teams = set() for circle in place: relevant_teams |= circle if len(circle) == 1: continue color_index, current_color = getcolor(color_index) for team in circle: gvcircles.add_node(asciiname(team), label = team.name, color = current_color, fontcolor = current_color) gvfull.get_node(asciiname(team)).attr['color'] = current_color gvfull.get_node(asciiname(team)).attr['fontcolor'] = current_color for source, dest, weight in team_graph.edges(): if source in circle and dest in circle: gvcircles.add_edge(asciiname(source), asciiname(dest), label = str(weight), color = current_color, fontcolor = current_color) gvfull.get_edge(asciiname(source), asciiname(dest)).attr['color'] = current_color gvfull.get_edge(asciiname(source), asciiname(dest)).attr['fontcolor'] = current_color place = [[(team.normalized_jugg_diff(relevant_teams), team.name, team) for team in circle] for circle in place] for circle in place: circle.sort(reverse = True) while place: place_list.append(set()) i = 0 while i < len(place): circle = place[i] jd = circle[0][0] while circle and circle[0][0] == jd: place_list[-1].add(circle.pop(0)) if not circle: place.remove(circle) else: i += 1 for same_place_set in place_list: # tie breaker if len(same_place_set) > 1: # teams that everyone on this place played against relevant_teams = team_graph.nodes() for circ_jugg_diff, name, team in same_place_set: opponents = set() for game in team.games(): if game.team_1 == team: opponents.add(game.team_2) else: opponents.add(game.team_1) relevant_teams &= opponents if len(relevant_teams) > 0: color_index, current_color_a = getcolor(color_index) color_index, current_color_b = getcolor(color_index) for team in relevant_teams: gvtiebreaker.add_node("b-" + asciiname(team), label = team.name, color = current_color_b, fontcolor = current_color_b) for void, void, team in same_place_set: gvtiebreaker.add_node("a-" + asciiname(team), label = team.name, color = current_color_a, fontcolor = current_color_a) for game in team.games(): if game.team_1 == team and game.team_2 in relevant_teams: if game.winner() == team: gvtiebreaker.add_edge("a-" + asciiname(team), "b-" + asciiname(game.team_2), label = game.jugg_diff(), color = current_color_a, fontcolor = current_color_a) else: gvtiebreaker.add_edge("b-" + asciiname(game.team_2), "a-" + asciiname(team), label = game.jugg_diff(), color = current_color_b, fontcolor = current_color_b) elif game.team_2 == team and game.team_1 in relevant_teams: if game.winner() == team: gvtiebreaker.add_edge("a-" + asciiname(team), "b-" + asciiname(game.team_1), label = game.jugg_diff(), color = current_color_a, fontcolor = current_color_a) else: gvtiebreaker.add_edge("b-" + asciiname(game.team_1), "a-" + asciiname(team), label = game.jugg_diff(), color = current_color_b, fontcolor = current_color_b) # jugg differences against relevant teams rel_jugg_diffs = set() for team_tuple in same_place_set: rel_jugg_diffs.add((team_tuple, team_tuple[2].normalized_jugg_diff(relevant_teams))) # pop all teams, highest relevant jugg difference first while rel_jugg_diffs: # current maximum max_rel_jugg_diff = None # teams with maximum jugg difference to_remove = None for team_tuple, rel_jugg_diff in rel_jugg_diffs: # new maximum if max_rel_jugg_diff is None or rel_jugg_diff > max_rel_jugg_diff[0]: max_rel_jugg_diff = (rel_jugg_diff, {team_tuple}) to_remove = {(team_tuple, rel_jugg_diff)} # same as maximum elif rel_jugg_diff == max_rel_jugg_diff[0]: max_rel_jugg_diff[1].add(team_tuple) to_remove.add((team_tuple, rel_jugg_diff)) # remove teams with maximum jugg difference rel_jugg_diffs -= to_remove # add teams to listing for (circ_jugg_diff, name, team), rel_jugg_diff in to_remove: RankedTeam.objects.create(place = current_place, team = team) current_place += 1 else: circ_jugg_diff, name, team = same_place_set.pop() RankedTeam.objects.create(place = current_place, team = team) current_place += 1 with tempfile.NamedTemporaryFile(suffix = ".png") as tmp: gvfull.draw(tmp, "png", "dot") pic = RankingPicture(user = user, image = File(tmp), title = "Full Team Graph") pic.save() with tempfile.NamedTemporaryFile(suffix = ".png") as tmp: gvcircles.draw(tmp, "png", "dot") pic = RankingPicture(user = user, image = File(tmp), title = "Circles") pic.save() with tempfile.NamedTemporaryFile(suffix = ".png") as tmp: gvtiebreaker.draw(tmp, "png", "dot") pic = RankingPicture(user = user, image = File(tmp), title = "Tie Breaker") pic.save()
class DotGraphSearchProblem(Problem): """ Playground for stuff in the library... eats a .dot graph and allows you to try it with the search methods. """ def __init__(self, filename): self.G = AGraph(filename) xs = [(nodo, nodo.attr.get("initial", None)) for nodo in self.G.iternodes()] xs = [x for x in xs if x[1]] if len(xs) == 0: raise BadInputGraph("Missing 'initial' node") elif len(xs) > 1: raise BadInputGraph("Cannot have two initial nodes") if not any(nodo.attr.get("goal", None) for nodo in self.G.iternodes()): raise BadInputGraph("Missing a goal state '[goal=\"1\"]'") super(DotGraphSearchProblem, self).__init__(xs[0][0]) self.initial_state.attr["shape"] = "doublecircle" for node in self.G.iternodes(): if self.is_goal(node): node.attr["shape"] = "hexagon" node.attr["color"] = "blue" self.seen = set() self.visit(self.initial_state) for edge in self.G.iteredges(): edge.attr["style"] = "dotted" x = edge.attr.get("weight", None) if x: x = int(x) else: x = 1 edge.attr["weight"] = x edge.attr["label"] = x def actions(self, state): assert state in self.G if self.G.is_directed(): return self.G.itersucc(state) else: assert self.G.is_undirected() return self.G.iterneighbors(state) def result(self, state, action): assert state in self.G and action in self.G self.visit(state) return action def cost(self, state1, action, state2): assert state1 in self.G and action in self.G and action == state2 x = self.G.get_edge(state1, state2).attr["weight"] if float(x) == int(x): return int(x) else: return float(x) def visit(self, state): if state in self.seen: return self.seen.add(state) attr = self.G.get_node(state).attr attr["color"] = "firebrick" def is_goal(self, state): return bool(state.attr.get("goal", False)) def value(self, state): assert state in self.G value = self.G.get_node(state).attr.get("value", None) if not value: return 0 return float(value)
class UiGraphio(QMainWindow): """ Main window for application """ def __init__(self): """ Constructor """ QMainWindow.__init__(self) self.ui = graphio.Ui_MainWindow() self.ui.setupUi(self) self.scene_graph = QGraphicsScene() self.ui.graphicsView.setScene(self.scene_graph) self.ui.graphicsView.update() self.graph = AGraph(strict=True, directed=True) self.graph.layout(prog='dot') ##################################################### # View update ##################################################### def update_adj_matrix(self): count = self.graph.number_of_nodes() self.ui.tw_adjmatrix.setRowCount(count) self.ui.tw_adjmatrix.setColumnCount(count) self.ui.tw_adjmatrix.setHorizontalHeaderLabels(self.graph.nodes()) self.ui.tw_adjmatrix.setVerticalHeaderLabels(self.graph.nodes()) for (i, u) in enumerate(self.graph.nodes()): for (j, v) in enumerate(self.graph.nodes_iter()): if self.graph.has_edge(u, v): self.ui.tw_adjmatrix.setItem( i, j, QTableWidgetItem( self.graph.get_edge(u, v).attr['label'])) else: self.ui.tw_adjmatrix.setItem(i, j, QTableWidgetItem(str(0))) def update_matrix_incidence(self): nodes = self.graph.nodes() edges = self.graph.edges() self.ui.tw_incmatrix.setRowCount(len(nodes)) self.ui.tw_incmatrix.setColumnCount(len(edges)) self.ui.tw_incmatrix.setHorizontalHeaderLabels( [str(node) for node in self.graph.edges()]) self.ui.tw_incmatrix.setVerticalHeaderLabels(self.graph.nodes()) for (i, u) in enumerate(nodes): for (j, edg) in enumerate(edges): value = 0 if (u == edg[0]): value = 1 elif (u == edg[1]): value = -1 self.ui.tw_incmatrix.setItem(i, j, QTableWidgetItem(str(value))) def update_list_edges(self): edges = self.graph.edges() self.ui.tw_edges.setRowCount(len(edges)) for (i, edge) in enumerate(edges): self.ui.tw_edges.setItem(i, 0, QTableWidgetItem(edge[0])) self.ui.tw_edges.setItem(i, 1, QTableWidgetItem(edge[1])) def update_adj_list(self): nodes = self.graph.nodes() self.ui.tw_adjlist.setRowCount(self.graph.number_of_nodes()) self.ui.tw_adjlist.setVerticalHeaderLabels(nodes) for (i, node) in enumerate(nodes): value = '' for adj in self.graph.out_edges(node): value += adj[1] + ', ' self.ui.tw_adjlist.setItem(i, 0, QTableWidgetItem(value[:-2])) ##################################################### # Reset editors ##################################################### def add_cb_item(self, label): n = self.ui.cb_nodes.count() i = 0 while i < n: itext = self.ui.cb_nodes.itemText(i) if label == itext: return elif label < itext: break i += 1 # insert item to lists self.ui.cb_nodes.insertItem(i, label) self.ui.cb_starting_node.insertItem(i, label) self.ui.cb_ending_node.insertItem(i, label) @pyqtSlot(bool, name='on_bt_add_node_clicked') @pyqtSlot(bool, name='on_bt_del_node_clicked') @pyqtSlot(bool, name='on_bt_add_edge_clicked') @pyqtSlot(bool, name='on_bt_del_edge_clicked') def reset_editors(self): self.ui.cb_nodes.clearEditText() self.ui.cb_starting_node.clearEditText() self.ui.cb_ending_node.clearEditText() self.ui.sb_weight_edge.setMinimum() def redraw(self): self.graph.draw('graph', 'png', 'dot') self.scene_graph.clear() self.scene_graph.addItem(QGraphicsPixmapItem(QPixmap('graph'))) self.ui.graphicsView.update() ##################################################### # Buttons actions ##################################################### @pyqtSlot() def on_bt_add_node_clicked(self): """ Slot when click on Add node button """ label = self.ui.cb_nodes.currentText() if not self.graph.has_node(label): self.add_cb_item(label) self.graph.add_node(label) self.redraw() @pyqtSlot() def on_bt_del_node_clicked(self): """ Slot when click on Delete node button """ index = self.ui.cb_nodes.currentIndex() label = self.ui.cb_nodes.currentText() if index > -1 and self.graph.has_node(label): self.graph.remove_node(label) self.redraw() self.ui.cb_nodes.removeItem(index) self.ui.cb_starting_node.removeItem(index) self.ui.cb_ending_node.removeItem(index) @pyqtSlot() def on_bt_add_edge_clicked(self): """ Slot when click on Add branch button """ start = self.ui.cb_starting_node.currentText() end = self.ui.cb_ending_node.currentText() weight = self.ui.sb_weight_edge.value() if start and end: self.add_cb_item(start) self.add_cb_item(end) self.graph.add_edge(start, end, label=weight) self.redraw() @pyqtSlot() def on_bt_del_edge_clicked(self): """ Slot when click on Delete branch button """ start = self.ui.cb_starting_node.currentText() end = self.ui.cb_ending_node.currentText() weight = self.ui.sb_weight_edge.value() if start and end and self.graph.has_edge(start, end): self.graph.remove_edge(start, end) self.redraw() @pyqtSlot(int) @pyqtSlot(bool, name='on_bt_add_node_clicked') @pyqtSlot(bool, name='on_bt_del_node_clicked') @pyqtSlot(bool, name='on_bt_add_edge_clicked') @pyqtSlot(bool, name='on_bt_del_edge_clicked') def on_toolbox_view_currentChanged(self, index): index = self.ui.toolbox_view.currentIndex() if index == 0: self.update_adj_matrix() elif index == 1: self.update_matrix_incidence() elif index == 2: self.update_list_edges() elif index == 3: self.update_adj_list()
def dot_layout(cy_elements): """ Get a CyElements object and augment it (in-place) with positions, widths, heights, and spline data from a dot based layout. Returns the object. """ elements = cy_elements.elements g = AGraph(directed=True, strict=False) # make transitive relations appear top to bottom # TODO: make this not specific to leader example elements = list(elements) nodes_by_id = dict( (e["data"]["id"], e) for e in elements if e["group"] == "nodes" ) order = [ (nodes_by_id[e["data"]["source"]], nodes_by_id[e["data"]["target"]]) for e in elements if e["group"] == "edges" and e["data"]["obj"] in ('reach', 'le') ] elements = topological_sort(elements, order, lambda e: e["data"]["id"]) # add nodes to the graph for e in elements: if e["group"] == "nodes": g.add_node(e["data"]["id"], label=e["data"]["label"].replace('\n', '\\n')) # TODO: remove this, it's specific to leader_demo weight = { 'reach': 10, 'le': 10, 'id': 1, } constraint = { 'pending': False, } # add edges to the graph for e in elements: if e["group"] == "edges": g.add_edge( e["data"]["source"], e["data"]["target"], e["data"]["id"], weight=weight.get(e["data"]["obj"], 0), #constraint=constraint.get(e["data"]["obj"], True), ) # add clusters clusters = defaultdict(list) for e in elements: if e["group"] == "nodes" and e["data"]["cluster"] is not None: clusters[e["data"]["cluster"]].append(e["data"]["id"]) for i, k in enumerate(sorted(clusters.keys())): g.add_subgraph( name='cluster_{}'.format(i), nbunch=clusters[k], ) # now get positions, heights, widths, and bsplines g.layout(prog='dot') for e in elements: if e["group"] == "nodes": attr = g.get_node(e["data"]["id"]).attr e["position"] = _to_position(attr['pos']) e["data"]["width"] = 72 * float(attr['width']) e["data"]["height"] = 72 * float(attr['height']) elif e["group"] == "edges": attr = g.get_edge(e["data"]["source"], e["data"]["target"], e["data"]["id"]).attr e["data"].update(_to_edge_position(attr['pos'])) g.draw('g.png') return cy_elements
def convert_to_a_graph(rdf_graph): multi_di_graph = rdflib_to_networkx_multidigraph(rdf_graph) directed = multi_di_graph.is_directed() strict = nx.number_of_selfloops( multi_di_graph) == 0 and not multi_di_graph.is_multigraph() a_graph = AGraph(name=multi_di_graph.name, strict=strict, directed=directed) a_graph.graph_attr.update( multi_di_graph.graph.get( "graph", { 'label': 'Network Map', 'fontsize': '16', 'fontcolor': 'white', 'bgcolor': '#333333', 'rankdir': 'BT', 'overlap': 'prism', 'splines': 'true' })) a_graph.node_attr.update( multi_di_graph.graph.get( "node", { 'fontname': 'Helvetica', 'fontcolor': 'white', 'color': '#006699', 'style': 'filled', 'fillcolor': '#006699', })) a_graph.edge_attr.update( multi_di_graph.graph.get( "edge", { 'style': 'dashed', 'color': 'green', 'arrowhead': 'open', 'fontname': 'Courier', 'fontsize': '14', 'fontcolor': 'white', })) a_graph.graph_attr.update((k, v) for k, v in multi_di_graph.graph.items() if k not in ("graph", "node", "edge")) for n, node_data in multi_di_graph.nodes(data=True): a_graph.add_node(n) a = a_graph.get_node(n) a.attr.update({k: str(v) for k, v in node_data.items()}) if multi_di_graph.is_multigraph(): for u, v, key, edge_data in multi_di_graph.edges(data=True, keys=True): str_edge_data = { k: str(v) for k, v in edge_data.items() if k != "key" } a_graph.add_edge(u, v, headlabel=str(key)) a = a_graph.get_edge(u, v) a.attr.update(str_edge_data) a_graph.layout() return a_graph