I am making a graph using NetworkX to export to visualize with Gephi. I've been adding various attributes to the nodes in my graph, without issue, until I tried adding colors. Does anyone know how to export a graph with "colored" nodes using networkx? (I've been writing into a gexf file, but don't care if it is another format as long as it is compatible with Gephi.)
Here is the code in which I make the graph:
def construct_weighted_graph(nodes, distance_dict, weighting_function, color = True):
G = nx.Graph()
#nodes automatically added when edges added.
for sequence in nodes: #loop through and add size attribute for num of sequences
G.add_node(sequence)
G.node[sequence]['size'] = distance_dict[sequence][1] #size represented by the node
if color:
G.node[sequence]['color'] = (0,1,0)
for i_node1 in range(len(nodes)):
dist_list = distance_dict[nodes[i_node1]][-2] #list of distances
for i_node2 in range(i_node1+1, len(nodes)):
G.add_edge(nodes[i_node1], nodes[i_node2],
weight = weighting_function(dist_list[i_node2]))
return G
That is not exactly what I have for color, since different nodes are assigned different colors, but it is the basic idea.
I ran into the exactly the same issue. The normal way to set coloring in NetworkX does not get exported to the GEXF format. By reading the export code of NetworkX and GEXF documentation, I have found out how to correctly export to GEXF and in turn import into Gephi.
NetworkX does export coloring if the coloring follows the same structure of GEXF. The data has to be added to a node inside a graph. So you add a key 'viz' standing for visualization to the node. You set 'viz' to another dictionary, where you add a key 'color' with in turn a dictionary with values for keys 'r','g','b', and 'a'.
I made a very simple example that demonstrates the solution:
import networkx as nx
""" Create a graph with three nodes"""
graph = nx.Graph()
graph.add_node('red')
graph.add_node('green')
graph.add_node('blue')
""" Add color data """
graph.node['red']['viz'] = {'color': {'r': 255, 'g': 0, 'b': 0, 'a': 0}}
graph.node['green']['viz'] = {'color': {'r': 0, 'g': 255, 'b': 0, 'a': 0}}
graph.node['blue']['viz'] = {'color': {'r': 0, 'g': 0, 'b': 255, 'a': 0}}
""" Write to GEXF """
# Use 1.2draft so you do not get a deprecated warning in Gelphi
nx.write_gexf(graph, "file.gexf", version="1.2draft")
This exports a graph with a red, a green, and a blue node to GEXF.
You have to change your example where you try to set the color to:
if color:
G.node[sequence]['viz'] = {'color': {'r': 0, 'g': 1, 'b': 0, 'a': 0}} # line changed
for i_node1 in range(len(nodes)):
networkx
conversion to GEXF format (version 1.1draft) is buggy for me too.
But this worked for me. I'm adding some extra code before and after the part you need, because this implies (in my cursory rereading of code that I wrote years ago but continue to use on this site: http://djotjog.com/c/wordtree/ -- because it still works) that you add the nodes to the DiGraph (G) then have to add them again in a different way ensure the RGB color
and size
format is coded inside the <node>
tags of the gexf file.
code...
G.add_nodes_from(nodes) #<--- assigns node names, and also node 'size', used below
for n in G.node:
n_size = G.node[n]['size']
G.add_node(n,viz={'color':{'r':"170",'b':"170",'g':"170",'a':"0.7"},'size':n_size})
#{'position':{'x':x,'y':y}}
G.add_weighted_edges_from(edges)
...
import codecs
f = codecs.open(gexf_filename, "wb", "utf-8") # unicode safe version of file-open
nx.write_gexf(G,f)
f.close()
Note: You could add more than just size and color to the 'viz' part, but every node must have a 'viz' dict for color to work. I also assigned alpha "a" here as part of RGBA format, but it doesn't seem to be appearing in my graphs. networkx strips that part out of GEXF. I think that is a bug. Elsewhere on stackoverflow I've discovered another networkx bug in not being able to control the namespace in the xml header.
That code yields GEXF XML nodes that look like this:
<?xml version="1.0" encoding="utf-8"?><gexf xmlns:ns0="http://www.gexf.net/1.1draft/viz" version="1.1" xmlns="http://www.gexf.net/1.1draft" xmlns:viz="http://www.gexf.net/1.1draft/viz" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/XMLSchema-instance">
<graph defaultedgetype="directed" mode="static">
<attributes class="node" mode="static">
<attribute id="0" title="size" type="integer" />
</attributes>
<nodes>
<node id="0" label="shop">
<ns0:color b="100" g="100" r="100" />
<ns0:size value="17" />
<attvalues>
<attvalue for="0" value="17" />
</attvalues>
</node>
Where the ns0:
part is crucial. Putting color in attvalues
doesn't translate into color in the graph.
This version has no color. And note that node 'size' MUST be defined in gexf format to work, and it must be an integer.
<?xml version='1.0' encoding='utf-8'?>
<gexf version="1.1" xmlns="http://www.gexf.net/1.1draft" xmlns:viz="http://www.gexf.net/1.1draft/viz" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/XMLSchema-instance">
<attributes class="node" mode="static">
<attribute id="0" title="category" type="string" />
<attribute id="1" title="color" type="string" />
<attribute id="2" title="size" type="integer" />
</attributes>
<node id="CarterCenter" label="CarterCenter">
<attvalues>
<attvalue for="0" value="open data" />
<attvalue for="1" value="blue" />
<attvalue for="2" value="0" />
</attvalues>
</node>
Here are two useful examples of files for debugging purposes:
http://djotjog.com/s/gexf-web2/data/ocp_network.gexf versus http://djotjog.com/s/gexf-web2/data/ocp_network_test.gexf
and you can see them render online here: http://djotjog.com/s/gexf-web2?file=data/ocp_network.gexf (WITH COLOR) and http://djotjog.com/s/gexf-web2?file=data/ocp_network_test.gexf (SAME CHART, without COLOR, but with alpha working.
来源:https://stackoverflow.com/questions/28522155/adding-color-attribute-to-nodes-on-networkx-to-export-to-gephi