Beispiel #1
0
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
Beispiel #2
0
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')
Beispiel #4
0
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)
Beispiel #5
0
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")
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
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')
Beispiel #9
0
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()
Beispiel #11
0
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)
Beispiel #12
0
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()
Beispiel #13
0
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
Beispiel #14
0
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