# Interactive Brain Graph Visualization(4): From fMRI to Json file

The code of this visualization is available on my github: https://github.com/astro1860/visualization_project/tree/master/brain_fisheye and you can see how to generate the json file by running the ipynb file.

**Getting data from fMRI**

The raw data used for visualization is obtained from fMRI(**f**unctional **m**agnetic **r**esonance **i**maging), using MRI with diffusion tensor imaging and tractography techniques. As the fMRI data can indicate activity of different brain areas, these data can be used to represent the brain and its connections as a graph. In the visualization, each node is a brain region of the Desikan-Killiany Atlas. Each link illustrates the connection between two brain regions. The data is read from .mat file and loaded to python with

The data we interested in are adjacency matrix of brain connections and the labels(names) of the brain areas. The adjacency matrix is the binary matrix, with “1″ representing connection existed and “0″ meaning no connections. We analyzed only with these two data sets.

**Add node and link attributes**

1. Add names as node attributes

As the name labels have prefix with “lh”& “rh” as left and right hemisphere information which are unnecessary for visualizations, we deleted the prefix and assign group with different hemisphere with the following code:

Labelsshort={}

group={}

for i in range(len(Brain_adj)):

Brain1labs[i]=Brain1labels[0][i][0]

if Brain1labs[i][0:2]=='lh':

group[i]=1

Labelsshort[i]=Brain1labs[i][3:]

elif Brain1labs[i][0:2]=='rh':

group[i]=2

Labelsshort[i]=Brain1labs[i][3:]

else:

group[i]=0

Labelsshort[i]=Brain1labs[i]

Meanwhile, we would like to the add the names as node attributes in visualization. With networkx, we did this function:

print "adding groups to the graph..."

g = graph

label_group = group

nx.set_node_attributes(g,'group',label_group)

return g,label_group

2. Add degrees centrality as node attributes

As explained before, the degree of a node is the number of edges it adjacent to and node with more degrees have more connections. While degree centrality is merely one step more than degree, representing the fraction of nodes it is connected to. We added the degree centrality as node attributes with this function:

print "Calculating Degree Centrality..."

g = graph

num_nodes = nx.number_of_nodes(g)

dc = nx.degree_centrality(g)

nx.set_node_attributes(g,'degree_cent',dc)

degcent_sorted = sorted(dc.items(), key=itemgetter(1), reverse=True)

for key,value in degcent_sorted[0:num_nodes-1]:

print "Highest degree Centrality:", key, value

return graph, dc

Noted that we also did with this function a ranking of degree centrality from the highest to the lowest, make it convenient in further visualizations.

3. Add eigenvector as node attributes

In blog post “Interactive Brain Visualization(2): simple visualizations with barbell graph“, we have introduced an important concept “eigenvector” and analyzed it mathematically.

We calculate the eigenvector centrality with the following steps:

1. Calculate the eigendecomposition of the pairwise adjacency matrix of the graph.

2. Select the eigenvector associated with largest eigenvalue.

3. Element i in the eigenvector gives the centrality of the i-th node.

The networkx package provides eigenvector_centrality to calculate the values. https://networkx.github.io/documentation/latest/reference/generated/networkx.algorithms.centrality.eigenvector_centrality.html#networkx.algorithms.centrality.eigenvector_centrality We calculated eigenvector centrality and performed a ranking from the highest to lowest with the a

print "Calculating Eigenvector Centrality..."

g = graph

ec = nx.eigenvector_centrality(g)

nx.set_node_attributes(g,'eigen_cent',ec)

eigen_sorted = sorted(eigen.items(), key=lambda(k,v):(float(v),k), reverse=True)

for key, val in eigen_sorted[0:num_nodes-1]:

print "highest eigenvector centrality nodes:", key, val

return g, ec

4. add x, y coordinates as node attributes

We extracted position of the brain activity areas with x and y coordinates and saved them in python dictionaries. With two functions: add_coordinates_x_attributes & add_coordinates_y_attributes, we successfully add the position attributes.

print "adding x to the graph..."

g = graph

nx.set_node_attributes(g,'x',xaxis)

return g,xaxis

print "adding y to the graph..."

g = graph

nx.set_node_attributes(g,'y',yaxis)

return g,yaxis

**Create json file**

To add those attributes, we need to call the functions:

g, eigen = calculate_eigenvector_centrality(g)

g, label = add_label_attributes(g)

g, group = add_group_attributes(g)

g,x = add_coordinates_x_attributes(g)

g,y = add_coordinates_y_attributes(g)

At this stage, we have finished adding nodes attributes. Let’s see what are the attributes of random node, saying node[13].

'degree_cent': 0.15853658536585366,

'eigen_cent': 0.059968386885244925,

'name': u'cuneus',

'x': 6.50724406627854,

'y': -76.454365427675796}

We saved these information to a position_graph.json file using the following function.

g = graph

g_json = json_graph.node_link_data(g)

json.dump(g_json, open(filename,'w'))

save_to_jsonfile("position_graph.json", g)

We will make use of the json file with a powerful tool: d3.js and create a series of interactive graphs.