Пример #1
0
    def run(self):
        layout = np.empty((self.max, 2))

        forceatlas2 = ForceAtlas2(adjustSizes=True,
                                  scalingRatio=RADIUS,
                                  verbose=False)

        clusters = sorted(self.graph.clusters(), key=len, reverse=True)
        dx, dy = 0, 0
        max_height = 0
        max_width = 0
        total_count = 0
        for i, ids in enumerate(clusters):
            if self.isStopped():
                self.canceled.emit()
                return False

            graph = self.graph.subgraph(ids)
            vcount = graph.vcount()
            radii = [
                self.radii[x] if self.radii[x] > 0 else RADIUS for x in ids
            ]

            if vcount == 1:
                lyt = ig.Layout([(0, 0)])
                border = 2 * radii[0]
            elif vcount == 2:
                lyt = ig.Layout([(0, -2 * radii[0]), (0, 2 * radii[1])])
                border = 2 * max(radii)
            else:
                lyt = forceatlas2.forceatlas2_igraph_layout(
                    graph,
                    pos=None,
                    sizes=radii,
                    iterations=1000,
                    weight_attr='__weight')
                border = 5 * max(radii)

            bb = lyt.bounding_box(border=border)
            lyt.translate(dx - bb.left, dy - bb.top)

            for coord, index in zip(lyt, ids):
                layout[index] = coord

            if max_width == 0:
                max_width = bb.width * 2

            dx += bb.width
            max_height = max(max_height, bb.height)
            if dx >= max_width:
                dx = 0
                dy += max_height
                max_height = 0

            total_count += vcount
            self.updated.emit(total_count)

        return layout, np.where(np.asarray(self.graph.degree()) < 1)[0]
Пример #2
0
 def __call__(self, layout):
     """ Process a MDS
     """
     from sklearn import manifold
     import scipy.spatial.distance as d
     if len(layout) > 0 and len(layout) != layout.dim:
         raise ValueError(
             'The layout should have same number of vertices and dimensions'
         )
     mat = np.array(layout.coords)
     mat = d.cdist(mat, mat, metric="cosine")
     if len(layout) == 0:
         result = []
     else:
         if layout.dim <= self.out_dim:
             result = np.hstack(
                 (mat, np.zeros(
                     (len(layout), self.out_dim - layout.dim)))).tolist()
         else:
             mds = manifold.MDS(self.out_dim,
                                max_iter=600,
                                n_init=30,
                                dissimilarity="precomputed")
             result = mds.fit_transform(mat).tolist()
     return ig.Layout(result, dim=self.out_dim)
Пример #3
0
def plot_the_result(dict_mdp, mdp_challenge):
    edge_list=topology_to_edge_list(mdp_challenge['T'])
    g = ig.Graph(edge_list)
    g.vs["name"] = dict_mdp['S']
    g.vs["reward"] = dict_mdp['R']
    g.vs["label"] = g.vs["name"]
    P_2D=list(mdp_challenge['P'].values())
    x_vec = [wlt[0] for wlt in P_2D]
    y_vec = [wlt[1] for wlt in P_2D]
    layout = ig.Layout(P_2D)
    g.vs["vertex_size"] = 20
    visual_style = {}
    visual_style["edge_curved"] = False
    colors = [(1, 0, 1) for i in range(0, len(dict_mdp['S']))]
    g.vs["color"] = colors
    fig = go.Figure()
    fig.add_trace(go.Scattergl(x=x_vec, y=y_vec, text=dict_mdp['S'],
                             mode='markers',
                             name='grid_points'))
    fig.add_trace(go.Scattergl(x=x_vec, y=y_vec,
                    mode='markers',
                    name='value_markers',
                    marker=dict(size=dict_mdp['U'],
                                         color=dict_mdp['U'])
                                         ))
    fig.show()
Пример #4
0
def visualize_temporal_unweighted(adja_mat,feature_names,full_feature_names,lag_range,all_variable_names,plotname="graph_temporal.pdf"):

    if isinstance(adja_mat,np.ndarray):
        adja_mat=adja_mat.tolist()

    gr=igraph.Graph.Weighted_Adjacency(adja_mat, mode="directed", attr="weight", loops=False)
    coord_list=[0]*len(all_variable_names)

    for ell in range(len(feature_names)):
        coord_list[all_variable_names.index(full_feature_names[ell])]=(0.5*ell,0+0.06*(-1)**ell)
        gr.vs[all_variable_names.index(full_feature_names[ell])]["name"]=feature_names[ell]
        for mmm in range(len(lag_range)):
            coord_list[all_variable_names.index(full_feature_names[ell]+'-'+str(lag_range[mmm]))]=(0.5*ell+0.01*(-1)**mmm,0.5*(mmm+1)+0.06*(-1)**ell)
            gr.vs[all_variable_names.index(full_feature_names[ell]+'-'+str(lag_range[mmm]))]["name"]=feature_names[ell]+'_'+str(lag_range[mmm])

    layout = igraph.Layout(coord_list)

    visual_style = {}
    visual_style["vertex_size"] = 20
    visual_style["vertex_label_size"]=6
    visual_style["vertex_color"] = [220,220,220]
    visual_style["vertex_shape"] = "rectangle"
    visual_style["vertex_label"] = gr.vs["name"]
    visual_style["edge_width"] = 1.2
    visual_style["edge_arrow_size"]=0.8
    visual_style["edge_arrow_width"]=0.8
    visual_style["edge_label_size"]=8
    visual_style["layout"] = layout
    visual_style["bbox"] = (800, 800)
    visual_style["margin"] = 40
    igraph.plot(gr,plotname,**visual_style)
Пример #5
0
def clonotype_network_igraph(adata,
                             neighbors_key="tcr_neighbors",
                             basis="clonotype_network"):
    """
    Get an `igraph` object representing the clonotype network.

    Parameters
    ----------
    adata
        annotated data matrix
    neighbors_key
        key in `adata.uns` where tcr neighborhood information is located
    basis
        key in `adata.obsm` where the network layout is stored. 
    
    Returns
    -------
    graph
        igraph object
    layout 
        corresponding igraph Layout object. 
    """
    import igraph as ig
    from .._util._graph import get_igraph_from_adjacency

    conn = adata.uns[neighbors_key]["connectivities"]
    idx = np.where(~np.any(np.isnan(adata.obsm["X_" + basis]), axis=1))[0]
    g = get_igraph_from_adjacency(conn).subgraph(idx)
    layout = ig.Layout(coords=adata.obsm["X_" + basis][idx, :].tolist())
    return g, layout
Пример #6
0
 def __call__(self, graph, length=None, add_loops=None):
     weight = None
     if self.weighted:
         weight = EDGE_WEIGHT_ATTR
     #TODO: manage loops weight !
     graph.to_undirected()
     coords = [prox.prox_markov_list(graph, [vtx.index], weight=weight, length=length, add_loops=add_loops) \
                     for vtx in graph.vs]
     return ig.Layout(coords, dim=len(coords))
Пример #7
0
 def __call__(self, layout):
     """ Process the random projection
     """
     if len(layout) == 0:
         return layout
     mat = np.array(layout.coords)
     mat_r = sc.rand(layout.dim, self.out_dim)
     result = mat.dot(mat_r)
     return ig.Layout(result.tolist())
Пример #8
0
def get_coords(g0, g1):
    """
    Keep the coordinates of graph g0 after certain nodes are deleted.
    G0: original graph
    G1: derived graph from G0 after certain nodes are deleted.
    """
    import igraph
    coords0 = g0['layout'].coords
    coords0 = dict([el for el in zip(g0.vs['name'], coords0)])
    coords1 = [coords0.get(v) for v in g1.vs['name']]
    return igraph.Layout(coords1)
Пример #9
0
def main():

    #---------------------------------------------------------------------#
    # Layout for simulated EEG
    idx, x, y, label = np.loadtxt('acticap64xy.csv',
                                  dtype={
                                      'names': ('idx', 'x', 'y', 'label'),
                                      'formats': ('i', 'f', 'f', 'U3')
                                  },
                                  delimiter=' ',
                                  unpack=True)
    loc = np.stack([x, y], axis=-1).tolist()
    layout = ig.Layout(loc)
    layout.mirror(1)

    # simulated connection
    prefix = 'sim_chaos_colpitts_p64_'
    suffix = '.mat'
    filename = [
        'r6', 'r6_LF', 'r6_LF_RP_iid', 'r6_LF+RP', 'r4_3r_iid', 'r4_3r_2inter',
        'r4_3r_3inter', 'r12'
    ]
    matname = 'conn_nt'

    for fname in filename:
        conn = comty.loadmat(os.path.join(prefix + fname + suffix), matname)
        conn_tmp = np.mean(conn, 2)
        g, w = comty.create_graph(conn_tmp,
                                  labels=label,
                                  rescale=False,
                                  lowbnd=0)
        comty.graph_plot(g,
                         layout,
                         clustering='fastgreedy',
                         savename=fname + '.png')

    #---------------------------------------------------------------------#
    # Layout for minimal EEG
    loc_min = np.array([[-1, 1], [1, 1], [2, -1], [0, -1], [-2, -1]]).tolist()
    label_min = np.array(['x1', 'x2', 'x3', 'x4', 'x5'])
    layout_min = ig.Layout(loc_min)
Пример #10
0
 def computeLayout(graph):
     was_directed = graph.is_directed()
     if not was_directed:
         graph.to_directed()
     sugi = [x[1] for x in graph.layout_sugiyama()[:len(graph.vs)]]
     if not was_directed:
         graph.to_undirected()
     rank_max = max(sugi)
     ranks = [(x / (rank_max / 2)) - 1 for x in sugi]
     prox_coords = ProxLayoutPCA(dim=dim - 1)(graph)
     return ig.Layout(
         [prox_coords[i] + [rank] for i, rank in enumerate(ranks)], dim=dim)
Пример #11
0
    def shake(self, layout):
        from scipy.spatial.distance import pdist, squareform
        iter_max = 50  # try to keep low

        layout_mat = np.array(layout.coords, dtype=float)
        nbs, nbdim = layout_mat.shape  # nb objets, nb dimension de l'espace
        deplacements = np.zeros(
            (nbs, nbdim))  # matrice des déplacement élémentaires
        # on calcul la taille des spheres,
        # l'heuristique c'est que l'on puisse mettre 10 spheres sur la largeur du layout
        # le layout fait 1 de large
        size_elem = 1. / 10.
        sizes = size_elem * np.ones((nbs))  # a pseudo sphere size

        # calcul la matrice des distances minimales entre sommets
        dists_min = (sizes[:, None] + sizes[None, :]) / 2
        dists_min -= np.diag(dists_min.diagonal())  # diagonal = 0

        chevauchement = True  # est-ce qu'il y a chevauchement entre les spheres ?
        nb_iter = 0
        while nb_iter < iter_max and chevauchement:
            nb_iter += 1
            # calcul des distances entre les spheres
            dists = pdist(layout_mat, 'euclidean')
            dists = squareform(dists, force='tomatrix')
            # si tout les distances sont sup a distance min
            chevauchement = (dists < dists_min).any()
            if not chevauchement:
                break
            # calcul des vecteurs de deplacement de chaque sphere (= somme des forces qui s'exerce sur chaque sommet)
            deplacements[:, :] = 0  # raz
            for source in range(nbs):
                for dest in range(source + 1, nbs):
                    if dists[source, dest] < dists_min[source, dest]:
                        # vecteur de deplacement de source vers dest
                        vect_depl = layout_mat[dest] - layout_mat[source]
                        # deplacement aléatoire si chevauchement parfait
                        vnorm = np.linalg.norm(vect_depl)
                        if vnorm < 1e-10:
                            vect_depl = np.random.random(nbdim)
                            vnorm = np.linalg.norm(vect_depl)
                        vect_depl /= vnorm  # normalisation
                        # force = prop a la difference entre dist min et dist réel
                        force = self.kelastic * (dists_min[source, dest] -
                                                 dists[source, dest])
                        deplacements[source, :] += -force * vect_depl
                        deplacements[dest, :] -= -force * vect_depl
            # mise a jour des positions
            layout_mat += deplacements

        layout = ig.Layout(layout_mat.tolist())
        layout = normalise(layout)
        return layout
Пример #12
0
    def __call__(self, graph, length=None, add_loops=None):
        assert "type" in graph.vs.attributes()
        weight = None
        if self.weighted:
            weight = EDGE_WEIGHT_ATTR

        coords = []
        for vtx in graph.vs:
            v_length = length - (length % 2) if vtx["type"] else length - (
                length % 2) + 1
            pline = prox.prox_markov_list(graph, [vtx.index],
                                          length=v_length,
                                          add_loops=False,
                                          weight=weight)
            coords.append(pline)
        return ig.Layout(coords)
Пример #13
0
def graphgen(N,
             directed=True,
             noigraph_gen=False,
             return_layout_as_object=True):
    """
    This function creates a directed lattice in d=2 where edges go up or right.
    The ig.Graph.Lattice function does not appear to create directed graphs well.
    Use plot_graph to test with a small N.

    Returns: a tuple (g,l) where g is an igraph object, and l is an igraph layout

    igraph does not check for uniqueness when adding vertices by name.

    noigraph_gen does not generate the igraph object. This is mostly used for debugging. It works best if asgenerator is set to false so that you get a list of vertices and edges.

    Oct 25 2017 The for loop in this function is very slow. An iterator that yields is definitely better since the for loop is run by the igraph creation routine.

    Oct 24 2017 This is a fairly inefficient function. Probably easier to add vertices by generating a list of names first. noigraph_gen simply retuns edges and vertices
    """

    if dbg >= 3:
        print('running graphgen as generator')
    verts = vertgen(N)
    edges = edgegen(N)

    # make a graph layout for plotting
    if not noigraph_gen:
        if dbg >= 3:
            print('generating new graph')
        try:
            g = ig.Graph(directed=directed)
            g.add_vertices(verts)
            g.add_edges(edges)
        except:
            print('Error in generating igraph')

        # make layout for plotting
        layoutlist = [(x, y) for x in range(N) for y in range(N)]

        if return_layout_as_object:
            return g, ig.Layout(layoutlist)
        else:
            return g, layoutlist
        #return g,ig.Layout(layoutlist)
    else:
        return ([x for x in verts], [x for x in edges])
Пример #14
0
    def __call__(self, layout):
        """ Process a PCA
        """
        if len(layout) > 0 and len(layout) != layout.dim:
            raise ValueError(
                'The layout should have same number of vertices and dimensions'
            )
        mat = np.array(layout.coords)
        if len(layout) == 0:
            result = []
        else:
            if layout.dim <= self.out_dim:
                result = np.hstack(
                    (mat, np.zeros(
                        (len(layout), self.out_dim - layout.dim)))).tolist()
            else:
                result = self.robust_pca(mat).tolist()

        return ig.Layout(result, dim=self.out_dim)
Пример #15
0
    def visualize_network(self):
        g = ig.Graph(self.mdp_dict['adjacency_list'])
        g.vs["name"] = self.mdp_dict['S']
        g.vs["reward"] = self.mdp_dict['R']
        g.vs["label"] = g.vs["name"]
        # vec=np.array(self.mdp_dict['U'])
        # p=np.var(vec)
        # if(p==0):
        #     print('error')
        #     exit()
        # color_dict = {0: "blue", 1: "green", 2: "cyan", 3: "yellow", 4: "pink", 5: "orange", 6: "red"}
        # try:
        #     codebook, _ = kmeans(vec, len(color_dict))
        #     cluster_indices, _ = vq(vec, codebook)
        # except:
        #     codebook
        #
        # sel=[]
        # am_max_cluster=np.max(cluster_indices)
        # for qrti in range(0, am_max_cluster+1):
        #     tre=qrti==cluster_indices
        #     new_candi=np.max(vec[tre])
        #     sel.append(new_candi)
        # sel=np.array(sel)
        # sort_idx=np.argsort(sel)
        # new_cluster_indices=[np.nan]*len(cluster_indices)
        # for count, qrt in enumerate(sort_idx):
        #     act_idx_bool=sort_idx[count]==cluster_indices
        #     act_idx=np.where(act_idx_bool)
        #     act_idx=act_idx[0].tolist()
        #     for t in act_idx:
        #         new_cluster_indices[t]=count
        #
        # colors = [color_dict[index] for index in new_cluster_indices]
        # g.vs["color"] = colors

        g.vs["vertex_size"] = 20
        visual_style = {}
        visual_style["edge_curved"] = False
        P_2D = [(wlt[0], wlt[1]) for wlt in self.mdp_dict['P']]
        layout = ig.Layout(P_2D)
        ig.plot(g)
Пример #16
0
def clonotype_network_igraph(
        adata: AnnData,
        basis="clonotype_network") -> Tuple[ig.Graph, ig.Layout]:
    """
    Get an `igraph` object representing the clonotype network.

    Requires running :func:`scirpy.tl.clonotype_network` before, to
    compute the layout.

    Parameters
    ----------
    adata
        Annotated data matrix.
    basis
        Key in `adata.obsm` where the network layout is stored.

    Returns
    -------
    graph
        igraph object
    layout
        corresponding igraph Layout object.
    """
    from ..util.graph import igraph_from_sparse_matrix

    try:
        clonotype_key = adata.uns[basis]["clonotype_key"]
    except KeyError:
        raise KeyError(
            f"{basis} not found in `adata.uns`. Did you run `tl.clonotype_network`?"
        )
    if f"X_{basis}" not in adata.obsm_keys():
        raise KeyError(
            f"X_{basis} not found in `adata.obsm`. Did you run `tl.clonotype_network`?"
        )
    coords, adj_mat = _graph_from_coordinates(adata, clonotype_key)

    graph = igraph_from_sparse_matrix(adj_mat, matrix_type="distance")
    # flip y axis to be consistent with networkx
    coords["y"] = np.max(coords["y"]) - coords["y"]
    layout = ig.Layout(coords=coords.loc[:, ["x", "y"]].values.tolist())
    return graph, layout
Пример #17
0
 def __call__(self, layout):
     """ run a TSNE
     """
     from sklearn import manifold
     if len(layout) > 0 and len(layout) != layout.dim:
         raise ValueError(
             'The layout should have same number of vertices and dimensions'
         )
     mat = np.array(layout.coords)
     if len(layout) == 0:
         result = []
     else:
         if layout.dim <= self.out_dim:
             result = np.hstack(
                 (mat, np.zeros(
                     (len(layout), self.out_dim - layout.dim)))).tolist()
         else:
             tsne = manifold.TSNE(self.out_dim, n_iter_without_progress=50)
             result = tsne.fit_transform(mat).tolist()
     return ig.Layout(result, dim=self.out_dim)
Пример #18
0
    def plot(self):

        states = [self.agents[i].feat[0] for i in range(self.n)]

        color_dict = {0: 'orange', 1: 'blue'}
        size_dict = {0: 8, 1: 2}

        positions = [(vs['pos_x'], vs['pos_y']) for vs in self.graph.vs]
        layout = igraph.Layout(positions)

        igraph.plot(self.graph, layout = layout, \
                    vertex_color = [color_dict[self.agents[i].feat[0]] \
                                     if self.agents[i].zealot != 1 else 'red' \
                                     for i in range(self.n)],
                    vertex_size = [size_dict[self.agents[i].feat[0]] \
                                     for i in range(self.n)],
                    edge_width = [2.00 if es['t'] != 'v' and \
                             self.agents[es.target].feat[0] == 0 and \
                             self.agents[es.source].feat[0] == 0
                             else 0.00 for es in self.graph.es])
Пример #19
0
def build_layout(graph, options):
    coords = []
    w = 0.6 * min(numpy.asarray(options.bbox))
    r = 0.8 * w / 2
    n = len(options.vertices)

    teta = numpy.linspace(-math.pi / 2, 2 * math.pi - math.pi / 2, num=n + 1)
    p = [numpy.asarray([r * math.cos(t), r * math.sin(t)]) for t in teta]

    for layer in range(n):
        p0 = p[layer]
        p1 = p[layer + 1]
        ni = options.vertices[layer]
        vec = p1 - p0
        s = 0.4 / (ni - 1)
        ci = [p0 + (0.3 + s * i) * vec for i in range(ni)]
        coords += ci

    layout = igraph.Layout(coords)

    return layout
Пример #20
0
 def __call__(self, graph, **kwargs):
     # split the graph in N connected components
     connected_components = graph.clusters()
     subgraphs = connected_components.subgraphs()
     # compute a list of vertex position (cc id, and id in subgraph)
     vertex_cc = []
     next_by_cc = [0] * len(connected_components)
     for cc_num in connected_components.membership:
         v_num = next_by_cc[cc_num]
         next_by_cc[cc_num] += 1
         vertex_cc.append((cc_num, v_num))
     # compute layout for each cc
     layout_mth = self._layout_mth
     layouts = [layout_mth(cc, **kwargs) for cc in subgraphs]
     # move each layout
     nb_cc = len(connected_components)
     ## full graph of CC
     cc_graph = ig.Graph.Full(nb_cc)
     ## compute a weight for each CC, the more nodes the more weight
     #cc_weight = [np.log(len(cc) + 1) for cc in connected_components]
     cc_weight = [len(cc) for cc in connected_components]
     #print(cc_weight)
     ## weights for the edges between CC
     wmax = 1. * max(cc_weight)
     weights = [
         2. * wmax - (cc_weight[edg.source] + cc_weight[edg.target])
         for edg in cc_graph.es
     ]
     ## Compute CC graph layout
     cc_layout = cc_graph.layout_fruchterman_reingold(weights=weights,
                                                      dim=self._merge_dim)
     for cc_num, layout in enumerate(layouts):
         cc_position = cc_layout[cc_num]
         # resize each small layout
         layout.fit_into([cc_weight[cc_num] / wmax] * layout.dim)
         layout.center(cc_position)
     # merge layouts
     layout = [layouts[cc_num][v_num] for cc_num, v_num in vertex_cc]
     return ig.Layout(layout)
Пример #21
0
def compute_Layout(graph_object, layout_type):
    graph_name = graph_object["name"]
    layout_name = graph_name + ("." if layout_type != "fr" else ".kk.") + layout_type + ".layout"
    layout_file = Path(layout_name)
    if layout_file.is_file():
        layout_file = open(layout_name, 'r')
        layout = ig.Layout(json.load(layout_file), 2)
        layout_file.close()
        return layout
    else:
        start = time.clock()
        print("Starting to compute " + LAYOUT_TYPE_NAMES[layout_type])
        if layout_type == "fr":
            layout = graph_object.layout(layout_type, weights="weight", seed = compute_Layout(graph_object, "kk")) #Takes way more than awhile
            #PROPERLY DONE LIST FOR FR
            #Uses Kamada Kawai for rough initial placement, then sets using Fruchterman Reingold with proper edge weights
        elif layout_type == "sugi":
            layout = graph_object.layout_sugiyama(layers=graph_object.vs["var_type"], weights="weight", hgap = (4 + max(graph_object.vs["size"])) * 2) #Change the hard coding
            visual_style["bbox"][0] *= 4
        elif layout_type == "fr_layer": #Not terribly useful considering the tendency to clump to the dividing line
            var_types = 1 + max(graph_object.vs["var_type"])
            layer_size = visual_style["bbox"][1] / var_types
            minY, maxY = [], []
            for i in range(var_types):
                minY.append(i * layer_size)
                maxY.append((i + 1) * layer_size)
            layout = graph_object.layout_fruchterman_reingold(weights="weight",
            miny=[minY[i] + visual_style["margin"][i % 2] for i in graph_object.vs["var_type"]],
            maxy=[maxY[i] + visual_style["margin"][(i + 1) % 2] for i in graph_object.vs["var_type"]])
        else:
            layout = graph_object.layout(layout_type)	#Takes awhile
        print("Layout computed in", time.clock() - start, "seconds")
        try:
            layout_file = open(layout_name, 'w')
            json.dump(layout.coords, layout_file, separators=(",",":"))
        except:
            print("Error saving " + layout_name)
        return layout
Пример #22
0
 def update_layout(self, layout=None, param=None):
     g = self.graph
     if self.layout_update_needed(layout, param):
         start_time = time.time()
         self.layout_param = self.layout_param if self.layout_param is not None \
             else self.layout_defaults[self.layout] if self.layout in self.layout_defaults \
             else {}
         msg = """Calculating %s layout... (numof nodes/edges: %u/%u)""" % \
             (self.layout, g.vcount(), g.ecount())
         sys.stdout.write('\t::%s' % msg)
         sys.stdout.flush()
         self._log(msg)
         if self.grouping is not None:
             if self.layout in [
                     "intergroup", "modular_fr", "modular_circle"
             ]:
                 f = getattr(gr_plot, "layout_%s" % self.layout)
                 f(g, self.grouping, self.layout_param)
             else:
                 if self.layout not in [
                         "fruchterman_reingold", "fr", "circle"
                 ]:
                     self.layout = "fr"
                 g['layout_data'] = layout_intergroup(
                     g, self.grouping, **self.layout_param)
                 g['layout_type'] = "layout_intergroup"
             if self.vertex_color == "groups":
                 self.colorize(what='vertex', coldef=self.grouping)
         self.layout = self.layout if layout is None else layout
         self.layout_param = self.layout_param if param is None else param
         self.layout_data = g.layout(self.layout, **self.layout_param)
         self.layout_data = igraph.Layout(self.layout_data)
         time_elapsed = time.time() - start_time
         m, s = divmod(time_elapsed, 60)
         time_elapsed_str = "%02d min %02d sec" % (m, s)
         sys.stdout.write(' Done in %s. \n' % time_elapsed_str)
         sys.stdout.flush()
Пример #23
0
def clonotype_network_igraph(adata,
                             basis="clonotype_network"
                             ) -> Tuple[ig.Graph, ig.Layout]:
    """
    Get an `igraph` object representing the clonotype network.

    Requires running :func:`scirpy.tl.clonotype_network` before, to 
    compute the layout. 

    Parameters
    ----------
    adata
        Annotated data matrix.
    basis
        Key in `adata.obsm` where the network layout is stored. 
    
    Returns
    -------
    graph
        igraph object
    layout 
        corresponding igraph Layout object. 
    """
    from ..util.graph import _get_igraph_from_adjacency

    try:
        neighbors_key = adata.uns[basis]["neighbors_key"]
    except KeyError:
        raise KeyError(
            f"{basis} not found in `adata.uns`. Did you run `tl.clonotype_network`?"
        )

    conn = adata.uns[neighbors_key]["connectivities"]
    idx = np.where(~np.any(np.isnan(adata.obsm["X_" + basis]), axis=1))[0]
    g = _get_igraph_from_adjacency(conn).subgraph(idx)
    layout = ig.Layout(coords=adata.obsm["X_" + basis][idx, :].tolist())
    return g, layout
Пример #24
0
def animate(g, layout = None, filename = "frame" , height = 800, rendermovie = True, outfile = 'anim'):
    """
    Rotate 3d layout of graph C{g} and export a C{.png} snapshot 
    for each angle.
    If found, the graphs vertex attributes C{size} and C{color}
    will be use. C{color} should be an RGB  tuple.
    If layout is None, a 3d C{FR} layout will be computed.

    @param g: an C{igraph.Graph} instance.
    @param layout: 3d igraph Layout. Optional.
    @param filename: filename prefix for C{.png} snapshots.
    @param height: height of output C{.png} files in pixels.
    @param rendermovie: whether or not to render a movie from the snapshots. Requires C{ffmpeg}.
    @param outfile: filename for output movie.
    """

    if 'size' not in g.vs.attribute_names():
        g.vs['size'] = g.degree() 
    
        
    if 'color' not in g.vs.attribute_names():
        g.vs['color'] = [(255,255,255)] * g.vcount()
    
    print "Framing the layout..."
    gg = frame_the_graph(g)

    if layout is None:
        print "computing 3d layout..."
        layout = g.layout_fruchterman_reingold_3d()


    #center the layout
    layout.center(layout.centroid()) 

    y_max = max([item[1] for item in layout.coords])
    x_max = max([item[0] for item in layout.coords])
    y_min = min([item[1] for item in layout.coords])
    x_min = min([item[0] for item in layout.coords])
    k = 1.5

    x_width = max([np.sqrt(point[0] ** 2 + point[2] ** 2) for point in layout.coords])    
    aspect = k*(x_max-x_min) / (y_max-y_min)

    fixed_coords = [[x_width*k,y_max],[x_width*k,y_min],[-x_width*k,y_min],[-x_width*k,y_max]]

    for i in range(360):
        rootpoint = layout.coords[0]
        rootpoint = (0,0,-10)
        layout.rotate(1, 0, 2, origin=rootpoint)
        coords2d = [point[:2] for point in layout.coords]
        
        new_layout = ig.Layout( coords2d +  fixed_coords)
        update_depths(gg,layout)
        
        ig.plot(gg,
            filename + '-%s.png' % str(i).zfill(3),
            vertex_color = gg.vs['color-2'],
            vertex_size = gg.vs['size'],
            vertex_frame_color = gg.vs['color-1'],
            layout = new_layout,
            edge_color = gg.es['color-1'],
            background='black',
            bbox=(0,0,int(aspect*height),height)
           )
    if rendermovie:
        result = os.system(' ffmpeg -y -r 60 -qscale 2 -i %s-%%03d.png %s.mp4' % (filename,outfile))
        if result != 0:
            print "Eerror: could not render movie with ffmpeg."
Пример #25
0
def graphgen(N,
             directed=True,
             noigraph_gen=False,
             return_layout_as_object=True,
             graph_shape='rectangle'):
    """
    This function creates a directed lattice in d=2 where edges go up or right.
    The ig.Graph.Lattice function does not appear to create directed graphs well.
    Use plot_graph to test with a small N.

    Returns: a tuple (g,l) where g is an igraph object, and l is an igraph layout

    directed=True   produces a directed lattice with only up/right paths. Currently the other functions cannot handle the undirected lattice

    noigraph_gen=True does not generate the igraph object. This is mostly used for debugging. 

    return_layout_as_object=True    returns the second return value as an igraph object

    graph_shape='rectangle' or 'triangle'
    If chosen to be a triangle, helps cut down on computation time for limit shape computations. This is because you do not want to limit shape to be truncated.

    igraph does not check for uniqueness when adding vertices by name.

    Oct 25 2017 The for loop in this function is very slow. An iterator that yields is definitely better since the for loop is run by the igraph creation routine.

    Oct 24 2017 This is a fairly inefficient function. Probably easier to add vertices by generating a list of names first. noigraph_gen simply retuns edges and vertices
    """

    if dbg >= 1:
        print('Start generating graph: ' + time.asctime())

    verts = vertgen(N, graph_shape=graph_shape)
    edges = edgegen(N, graph_shape=graph_shape)

    if dbg >= 1:
        print('Done generating vertex and edge lists: ' + time.asctime())

    # make a graph layout for plotting
    if not noigraph_gen:
        if dbg >= 3:
            print('generating new graph')
        try:
            g = ig.Graph(directed=directed)
            #import ipdb; ipdb.set_trace()
            g.add_vertices(verts)
            g.add_edges(edges)
        except:
            print('Error in generating igraph')

        # make layout for plotting
        if graph_shape == 'rectangle':
            layoutlist = [(x, y) for x in range(N) for y in range(N)]
        elif graph_shape == 'triangle':
            layoutlist = [(x, y) for x in range(N) for y in range(N - x)]

        if dbg >= 1:
            print('Done generating igraph object and layout: ' +
                  time.asctime())

        if return_layout_as_object:
            return g, ig.Layout(layoutlist)
        else:
            return g, layoutlist
    else:
        # if noigraph_gen == True
        return ([x for x in verts], [x for x in edges])
Пример #26
0
def get_location_plot(neurons, positions, connections, savefile=None):
    """Plots a location of neurons in Allen common framework, colorcoded by location, with connection edges
        neurons: list of indices of neurons, corresponding to the indices in the connection tuples
        positions: [(x,y,z,brain_location)]
            x,y,z are coordinates in the Allen common framework
            brain_location is a string describing the brain location of a neuron
            - position(neuron[i]) = positions[i]
        connections: [(source,target)]
            source/target is the index of the source/target neuron in the connection. 
            The source/target index does not access the neurons array, rather, it corresponds 
            to an index that is in the neurons array.  
    """

    ### GET EDGES
    xe = []
    ye = []
    ze = []
    ws = []
    for i, j, w in connections:
        xe += [positions[i][0], positions[j][0], None]
        ye += [positions[i][1], positions[j][1], None]
        ze += [positions[i][2], positions[j][2], None]
        ws += w
    ### GET POSITIONS, leaving out brain_location string
    positions_just3d = np.array([(x, y, z)
                                 for (x, y, z, _) in positions[neurons]])
    xyz = [np.array(i) for i in zip(*positions_just3d)]

    ### GET BRAIN LOCATION labels
    locations = np.array([l for (_, _, _, l) in positions[neurons]])

    ## GET COLORS TO MATCH BRAIN LOCATION
    ind_locations = list(set(locations))

    colors = []
    for loc in locations:
        colors.append((ind_locations.index(loc) + 1) * 1 / len(ind_locations))

    ## PLOTTING
    layt = ig.Layout(coords=list(positions_just3d))

    trace1 = go.Scatter3d(x=xe,
                          y=ye,
                          z=ze,
                          mode='lines',
                          line=dict(color='rgb(125,125,125)', width=1),
                          text=ws,
                          hoverinfo='text',
                          name='functional connections')

    trace2 = go.Scatter3d(x=xyz[0],
                          y=xyz[1],
                          z=xyz[2],
                          mode='markers',
                          marker=dict(symbol='circle',
                                      size=6,
                                      color=colors,
                                      colorscale='Viridis',
                                      line=dict(color='rgb(50,50,50)',
                                                width=0.5)),
                          text=locations,
                          hoverinfo='text',
                          name='neurons')

    data = [trace1, trace2]
    fig = go.Figure(data=data)
    iplot(fig, filename='Bi-directionally connected bursting neurons')

    if savefile is not None:

        fig.write_html(savefile)
Пример #27
0
# # To embed users, we do Uuser = user x (v2^-1)' x s2^-1
# # So lets save the right multiplier
# user_embed = np.matmul(np.transpose(np.linalg.inv(v_t2)), np.linalg.inv(s_t2))

### Embedding?
# The L/R matrices above are the embeddings for our observed nodes

### Plotting?
# Need an igraph, along with a layout
num_users = B.shape[0]
num_subs = B.shape[1]
zero_u = np.zeros((num_users, num_users))
zero_s = np.zeros((num_subs, num_subs))

A = np.block([[zero_u, B], [np.transpose(B), zero_s]])
layout = np.block([[u_t2], [np.transpose(v_t2)]])

full_graph = ig.Graph.Adjacency(A.tolist(), mode=ig.ADJ_MAX)

# Adding attributes to the nodes.
for i in range(0, num_users):
    full_graph.vs[i]["color"] = "blue"

for i in range(num_users, num_subs + num_users - 1):
    full_graph.vs[i]["color"] = "red"

g_layout = ig.Layout(layout.tolist())

testplot(full_graph, g_layout, filename=PLOT_FN)
Пример #28
0
def graph_style(graph, visual_style=None):
    """
    
        args:
            graph: graph
            
        return:
            visual_style: a dictionary containing the visualization style
    """

    if visual_style is None:
        visual_style = dict()
        print("visual_style is None")

    # vertex color
#     if not 'vertex_color' in visual_style.keys():

#         try:
#             "set vertex  color based on vs attribute area"

#             # unique areas
#             uniqarea = list(set(graph.vs["area"]))

#             # set palette
#             palette = igcolors.ClusterColoringPalette(len(uniqarea))

#             # set vertex color
#             visual_style['vertex_color'] = [palette[uniqarea.index(area)] for area in graph.vs["area"]]

#         except KeyError:
#             visual_style['vertex_color'] =  'black'

# vertex size
    visual_style['vertex_size'] = 10
    # outdegree = graph.outdegree()
    # if max(outdegree) > 0:
    #     visual_style['vertex_size'] = [x/max(outdegree)*10+5 for x in outdegree]

    # vertex label size
    visual_style['vertex_label_size'] = 2

    # vertex label distance
    visual_style['vertex_label_dist'] = 2

    # vertex label color
    visual_style['vertex_label_color'] = 'black'

    # vertex label name
    try:
        visual_style["vertex_label"] = graph.vs['name']

    except KeyError:
        print("No vertex name")

    # vertext label size
    visual_style["vertex_label_size"] = 20

    visual_style["vertex_label_angle"] = 0

    # the outdegree for each vertex
    outdegree = graph.outdegree()

    visual_style["margin"] = 100

    visual_style['edge_width'] = 0.35

    # set edge width if not exist
    if not 'edge_width' in visual_style.keys():
        visual_style['edge_width'] = graph.es['weight'] * 10

    # set edge color if not exist
    if not 'edge_color' in visual_style.keys():
        print("Use default edge color")

    # layout
    try:
        "set vertex  layout based on vs attribute coordinate coord"
        visual_style['layout'] = ig.Layout(graph.vs["coord"])

    except KeyError:
        print("Does not have a user defined layout, use the default.")

    return visual_style
Пример #29
0
    def layout(self, ly_alg = "Fruchterman-Reingold", directed_graph=True):

        if ly_alg not in SUPPORTED_LAYOUTS:
            return {
                "graph_ready": False,
                "errors": "Unsuspported layout algorithm"
            }

        print "VIZUALISATION TIMER: igraph layouting :",datetime.now() 
        ly_start = datetime.now()

        #new layouting by rcattano
        dimension = 2
        max_it = 500
        temp = 1
        nodes = len(self.igraph.vs)
        edges = np.array( [edge.tuple for edge in self.igraph.es], np.int32)

        _l = len(edges)

        pos = fl.layout_fr(nodes*dimension, edges, max_it, temp )

        #get the Layout object here. 
        #http://igraph.org/python/doc/igraph.layout.Layout-class.html
        scl =  int( _l/ 100 ) #int( _l * _l / 10 )
        if ly_alg == "Fruchterman-Reingold":
            ly = igraph.Layout(tuple(zip(pos[0:nodes], pos[nodes:2*nodes])))
            scl = scl / 3
        elif ly_alg == "LGL":
            ly = self.igraph.layout_lgl()
        elif ly_alg == "Kamada-Kawai":
            ly = self.igraph.layout_kamada_kawai()
            scl = scl / 10
        elif ly_alg == "Star":
            ly = self.igraph.layout_star()
            scl =  scl * 2
        elif ly_alg == "Random":
            ly = self.igraph.layout_random()
            scl =  scl * 2
        else:
            #ly = igraph.Layout( tuple(map(tuple, pos )) )
            #scl = scl / 3
            ly = self.igraph.layout_fruchterman_reingold(dim=2,coolexp =1, area = int( _l * _l / 10 ) )
            #ly_alg = "Fruchterman-Reingold"
            #OR standard fruchterman reingold
            
        ly_end = datetime.now()
        diff = ly_end - ly_start

        print "VIZUALISATION TIMER: returning coordinates :",ly_end
        print "Layouting took :", diff.seconds, "seconds using", ly_alg 

        # TODO screws up positioning for graphs with few nodes
        #ly.scale( scl * 4)

        box = ly.bounding_box()
        width = abs(box.left) + abs(box.right)

        coords = ly.__dict__['_coords']
        #numpy.float64 cannot be jsonified later, so we convert to standard float:
        coords = [ [ float( c[0] )* 1 , float( c[1] ) * 1 ] for c in coords  ]

        #todo we have the node names somewhere already ...
        vertices = []
        for i in self.igraph.vs:
            vertices.append( i['name'] )

        all_coords = dict( zip( vertices, coords ) )

        #add coords to each layer and get the nodes in each layer intersect with the nodes in the next layer
        layer_neighborhoods = []
        for i,_l in enumerate(self.layer_names):
            _layer_data = self.data[_l]

            _layer_data['name'] = _l

            try:
                _layer_data_next = data[ self.layer_names[i+1] ]
            except:
                #last layer
                _layer_data_next = self.data[ self.layer_names[i-1] ]

            #possible with namedtuples
            #nodes1 = _layer_data.nodes
            #nodes2 = _layer_data_next.nodes
            #indegs = _layer_data.in_degrees
            max_in_deg = 0
            max_out_deg = 0
            max_total_deg = 0
            nodes1 = _layer_data['nodes']
            nodes2 = _layer_data_next['nodes']
            indegs = _layer_data['in_degrees']
            outdegs = _layer_data['out_degrees']

            coords = {}
            common_nodes = list(  set( nodes1 ).intersection( set( nodes2 ) ) )

            for node_id in nodes1:
                _common = 1 if node_id in common_nodes else 0
                try:
                    indeg = indegs[ node_id ]
                    outdeg = outdegs[ node_id ]
                except Exception,e:
                    indeg = 0
                    outdeg = 0
                coords[node_id] = [ all_coords[ node_id ], _common, indeg, outdeg, indeg + outdeg, self.custom_scale.get(node_id, 1)] 

                max_out_deg = max(max_out_deg, outdeg)
                max_in_deg = max(max_in_deg, indeg)
                max_total_deg = max(max_total_deg, outdeg + indeg)
            #possible with namedtuples
            #_layer_data.coords = coords

            _layer_data['coords'] = coords

            # add dummy 0 values, so max_in_degree and max_out_degree have to 
            # same offset as the node's degrees
            _layer_data['maxDeg'] = [0, 0, max_in_deg, max_out_deg, max_total_deg, 1.0] 

            if directed_graph:
                get_key = lambda v1, v2: ''.join([v1, v2])
            else:
                get_key = lambda v1, v2: ''.join(sorted([v1, v2]))

            edge_dict = { get_key(x[0], x[1]):  x[2] for x in _layer_data['edges']}

            neighborhood = {}
            for i, nb in enumerate(self.igraph.neighborhood()):
                l = []
                neighborhood[vertices[i]] = neighborhood.get(vertices[i], l)  + [[vertices[j], edge_dict[get_key(vertices[i], vertices[j])]] for j in nb if get_key(vertices[i], vertices[j]) in edge_dict]
            _layer_data['neighborhood'] = neighborhood
Пример #30
0
        graph = igraph.Graph.Read( tmp_name , directed=directed_graph,format="ncol",weights=False )

        #new layouting by rcattano
        dimension = 2
        max_it = 500
        temp = 1
        nodes = len(graph.vs)
        edges = np.array( [edge.tuple for edge in graph.es], np.int32)

        pos = fl.layout_fr(nodes*dimension, edges, max_it, temp )

        #get the Layout object here. 
        #http://igraph.org/python/doc/igraph.layout.Layout-class.html
        scl =  int( _l/ 100 ) #int( _l * _l / 10 )
        if ly_alg == "Fruchterman-Reingold":
            ly = igraph.Layout(tuple(zip(pos[0:nodes], pos[nodes:2*nodes])))
            scl = scl / 3
        elif ly_alg == "LGL":
            ly = graph.layout_lgl()
        elif ly_alg == "Kamada-Kawai":
            ly = graph.layout_kamada_kawai()
            scl = scl / 10
        elif ly_alg == "Star":
            ly = graph.layout_star()
            scl =  scl * 2
        elif ly_alg == "Random":
            ly = graph.layout_random()
            scl =  scl * 2
        else:
            #ly = igraph.Layout( tuple(map(tuple, pos )) )
            #scl = scl / 3