Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

legend in python networkx

I have the following code to draw a graph with nodes but i am failing to add a proper legend: (sorry, i can't post an image it seems i don't have enough reputation)

I want a legend with the 4 colors, such as "light blue = obsolese, red = Draft, Yellow = realease, dark blue = init".

I have seen some solutions with "scatter" but i think it is too complicated. Is there a way to do it with plt.legend(G.nodes)?

Here is the code:

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
G=nx.Graph()
G.add_node("kind1")
G.add_node("kind2")
G.add_node("Obsolete")
G.add_node("Draft")
G.add_node("Release")
G.add_node("Initialisation")
val_map = {'kind1': 2,'kind2': 2,'Obsolete': 2,'Initialisation': 1,'Draft': 4,'Release': 3}
values = [val_map.get(node, 0) for node in G.nodes()]
nodes = nx.draw(G, cmap = plt.get_cmap('jet'), node_color = values)

plt.legend(G.nodes())
plt.show() 
like image 702
Dupond Avatar asked Apr 10 '14 15:04

Dupond


People also ask

What is legend in Python?

Legends can be placed in various positions: A legend can be placed inside or outside the chart and the position can be moved. The legend() method adds the legend to the plot. In this article we will show you some examples of legends using matplotlib. Related course. Data Visualization with Matplotlib and Python.

What is Nbunch in NetworkX?

An nbunch is a single node, container of nodes or None (representing all nodes). It can be a list, set, graph, etc.. To filter an nbunch so that only nodes actually in G appear, use G. nbunch_iter(nbunch) .


2 Answers

It seems that there is some kind of error when you are using nx.draw. Try to use nx.draw_networkx instead. And then use an axis from matplotlib to pass it when drawing the graph. This axis should contain the labels and colors of your nodes while plotting a point in (0,0) --> This is the tricky part.

Hope it helps! Here is the code I ran:

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
# For color mapping
import matplotlib.colors as colors
import matplotlib.cm as cmx

G=nx.Graph()
G.add_node("kind1")
G.add_node("kind2")
G.add_node("Obsolete")
G.add_node("Draft")
G.add_node("Release")
G.add_node("Initialisation")

# You were missing the position.
pos=nx.spring_layout(G)
val_map = {'kind1': 2, 
           'kind2': 2, 
           'Obsolete': 2, 
           'Initialisation': 1, 
           'Draft': 4, 
           'Release': 3}
values = [val_map.get(node, 0) for node in G.nodes()]
# Color mapping
jet = cm = plt.get_cmap('jet')
cNorm  = colors.Normalize(vmin=0, vmax=max(values))
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)

# Using a figure to use it as a parameter when calling nx.draw_networkx
f = plt.figure(1)
ax = f.add_subplot(1,1,1)
for label in val_map:
    ax.plot([0],[0],
            color=scalarMap.to_rgba(val_map[label]),
            label=label)

# Just fixed the color map
nx.draw_networkx(G,pos, cmap=jet, vmin=0, vmax=max(values),
                 node_color=values,
                 with_labels=False, ax=ax)

# Here is were I get an error with your code                                                                                                                         
#nodes = nx.draw(G, cmap=plt.get_cmap('jet'), node_color=values)                                                                             

# Setting it to how it was looking before.                                                                                                              
plt.axis('off')
f.set_facecolor('w')

plt.legend(loc='center')

f.tight_layout()
plt.show()

Some useful sources:

  1. http://pydoc.net/Python/networkx/1.0.1/networkx.drawing.nx_pylab/
  2. http://matplotlib.org/api/legend_api.html
  3. Using Colormaps to set color of line in matplotlib
  4. http://matplotlib.org/1.3.1/users/artists.html
like image 198
pequetrefe Avatar answered Oct 18 '22 05:10

pequetrefe


Thank you so much for your help, but it was not exactly what I wanted. I made few changes, so I can have the color legend's names differents from the nodes' names.

Here is the final code :

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
# For color mapping
import matplotlib.colors as colors
import matplotlib.cm as cmx

G=nx.Graph()
G.add_node("kind1")
G.add_node("kind2")
G.add_node("kind3")
G.add_node("kind4")
G.add_node("kind5")
G.add_node("kind6")

# You were missing the position.
pos=nx.spring_layout(G)
val_map = {'kind1': 2,'kind2': 2,'kind3': 2,'kind4': 1,'kind5':4,'kind6': 3}
#I had this list for the name corresponding t the color but different from the node name
ColorLegend = {'Obsolete': 2,'Initialisation': 1,'Draft': 4,'Release': 3}
values = [val_map.get(node, 0) for node in G.nodes()]
# Color mapping
jet = cm = plt.get_cmap('jet')
cNorm  = colors.Normalize(vmin=0, vmax=max(values))
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)

# Using a figure to use it as a parameter when calling nx.draw_networkx
f = plt.figure(1)
ax = f.add_subplot(1,1,1)
for label in ColorLegend:
    ax.plot([0],[0],color=scalarMap.to_rgba(ColorLegend[label]),label=label)

# Just fixed the color map
nx.draw_networkx(G,pos, cmap = jet, vmin=0, vmax= max(values),node_color=values,with_labels=True,ax=ax)

# Setting it to how it was looking before.                                                                                                              
plt.axis('off')
f.set_facecolor('w')

plt.legend()

f.tight_layout()
plt.show()

like image 41
Dupond Avatar answered Oct 18 '22 03:10

Dupond