Jules Massart
Jules Massart

Reputation: 75

Python networkx : show diiferent colors for one node

I have a list of sub-graphs and I want print it in one picture, I added all the nodes in the graph G, but I want to keep information of my sub-graphs, so I have give one color to each node and when a node belong of 2 sub-graphs, it has 2 colors (3 is belong 3, 4 to 4, ...).

My problem is to show the nodes with all of theirs colors parts and their labels in one picture, of course at the wright positions. I want to add a background in the picture too, and this picture doesn't appear in the same plot, but I would show it in the same plot.

plt.figure(figsize=(22,18))

plt.imshow(background, origin='lower', cmap="binary", alpha=0.5)

nodes = nx.draw_networkx_nodes(G, pos=posi)
nx.draw_networkx_labels(G, pos=posi)

for node in G.nodes() :
   plt.pie([1]*pgm, center=posi[node], colors = [cmap(a) for a in colors[node]])
plt.show()
plt.close()

I was inspired by Creating piechart as nodes in Networkx.

Do you know how can I give different colors to a same node and print theirs labels, and the background in the same picture ?

Upvotes: 2

Views: 500

Answers (3)

warped
warped

Reputation: 9481

not elegant or efficient, but I think this should do what you want

# dummy graph
df1 = pd.DataFrame({a:np.random.randint(0,8,100) for a in 'ab'})
df2 = pd.DataFrame({a:np.random.randint(5,15,100) for a in 'ab'})
df3 = pd.DataFrame({a:np.random.randint(12,20,100) for a in 'ab'})
df4 = pd.DataFrame({a:np.random.randint(19,25,100) for a in 'ab'})

graphs = []

for i, df in enumerate([df1,df2,df3,df4]):
    G = nx.from_pandas_edgelist(df, source='a', target='b')
    for node in G.nodes:
        G.nodes[node]['part_of'] = []
    graphs.append(G.copy())

F = nx.Graph()
for G in graphs:
    F = nx.compose(F,G)


# actual answer

for node in F.nodes():
    for i, G in enumerate(graphs):        
        if node in G.nodes():
            F.nodes[node]['part_of'].append(i)

pos = nx.spring_layout(F)

fig = plt.figure(figsize=(10,10))
cmap=plt.cm.viridis

nx.draw_networkx_edges(F, pos=pos,)

for node in F.nodes():
    part_of = list(set(F.nodes[node]['part_of']))
    w = plt.pie(
        [1]*len(part_of),
        center= pos[node],
        colors=[cmap(q/len(graphs)) for q in part_of],
        radius=0.05,
    )

plt.xlim(-2,2)
plt.ylim(-2,2)

enter image description here

Upvotes: 1

Jules Massart
Jules Massart

Reputation: 75

I have something like that :

def plot3(List, background) :

    graphs = []

    for i, df in enumerate(List[0]):
        G = List[0][i]
        for node in G.nodes:
            G.nodes[node]['part_of'] = []
        graphs.append(G.copy())


    F = nx.Graph()
    for G in graphs:
        F = nx.compose(F,G)
    nx.draw(F)
    print(F.number_of_nodes(), F.number_of_edges())
    print(len(List[0]))

    for node in F.nodes():
        for i, G in enumerate(graphs):        
            if node in G.nodes():
                F.nodes[node]['part_of'].append(i)

    pos = nx.spring_layout(F)

    fig = plt.figure(figsize=(10,10))

    nx.draw_networkx_edges(F, with_labels=False, node_size=50, pos=pos, alpha=.3)# node_color=colors,

    cmap=plt.cm.viridis

    for node in F.nodes():
        part_of = list(set(F.nodes[node]['part_of']))
        w = plt.pie(
            [1]*len(part_of),
            center= pos[node],
            colors=[cmap(q/len(graphs)) for q in part_of],
            radius=0.05,
        )

    return 1

enter image description here

Upvotes: 0

Jules Massart
Jules Massart

Reputation: 75

enter image description here

def plotGraph2(List_sous_graphe, background) :
    SS_Graphe = renomme_ss_graphe(List_sous_graphe)
    for popu in range(0,1) :
        vim = 0
        vmax = len(SS_Graphe[popu])
        G = nx.Graph()
        colors_n = {}
        nb_col_n = {}
        size_n = {}
        for g in range(vim, vmax):
            taille_noeud = SS_Graphe[popu][g].graph['support']
            #couleur c'est g le numéro du graphe
            #color i the g number
            for n in SS_Graphe[popu][g].nodes():
                if not G.has_node(n) :
                    colors_n [n] = [g]
                    nb_col_n [n] = 1
                    size_n [n] = taille_noeud
                    G.add_node(n)
                    #print("N'a pas")
                else :
                    #print(SS_Graphe[popu][g].nodes[n])
                    colors_n [n].append(g)
                    nb_col_n [n] = nb_col_n [n] + 1

    max_value_n = max(nb_col_n.values())

    pgm = plus_grand_mutiple(max_value_n)

    #Pour chaque noeud
    for n in colors_n :
        tab[n] = []
        #Pour chaque couleur du noeud
        for i in range(0, nb_col_n[n]) :
            #On rajoute chaque couleur un nombre de fois pgm divisé par le nombre de couleur du noeud
            #print(pgm/nb_col_n[n])
            for j in range(0, int(pgm/nb_col_n[n])):
                #print(colors_n[n])
                tab[n].append(colors_n[n][i])

    a = np.array(list(tab.values()))
    maxes = np.max(a, axis=0)

    colors= {}
    for key, val in tab.items():
        colors[key] = list(np.array(val)/maxes)

    #Then the plt.pie that you see in the above message

You can see some nodes has 2 colors : https://media.discordapp.net/attachments/590286639075688449/723124784988160000/Capture_decran_de_2020-06-18_12-36-46.png?width=536&height=410 It's a part of my picture i just take a screenshot

Sorry for french comment in my code, sometimes i forgot to comment in english

My pictures

Upvotes: 0

Related Questions