User Tutorial - Exporting from Matlab to Pajek

Updated for release version: mgui-1.0.10-alpha

This tutorial will explain how to export an adjacency matrix from Matlab to a graph in Pajek format, which can be read into the mgui environment. See here for a tutorial on how to load and visualize a Pajek graph.

Introduction

If you work with graphs in Matlab, but wish to visualize them using ModelGUI, then this nifty little tutorial is for you (if not, you could always go here). The process requires a Matlab script called write_matrix_to_pajek. For the purposes of the tutorial, you'll also need the script get_random_graph.

Note: Pajek is a nifty tool for 2D visualization, as well as computations, on graphs. Check it out here.

The Script

In Matlab, ensuring the required scripts are in your path, type:

 >> help write_matrix_to_pajek

 WRITE_MATRIX_TO_PAJEK writes an adjacency matrix representing a graph to 
 Pajek format, which can be read using the Pajek graph visualization tool, 
 as well as the modelGUI application.

 Arguments:

 matrix          A square adjacency matrix
 path            The path specify the Pajek output file
 varargin        Parameters refining the export:
                       'weighted' [true/false]: whether to use the matrix
                       values as edge weights (default = true).
                       'threshold_low': the low threshold at which to
                       include an edge (default = 0).
                       'threshold_high': the high threshold at which to
                       include an edge (default = realmax).
                       'directed': whether the edges are directed (default 
                       = true); in this case, the rule is column -> row
                       'labels': an N x 1 vector of vertex labels
                       (default = none).
                       'coords': an N x 3 matrix of vertex coordinates
                       (default = none).

 Author: Andrew Reid, BIC, MNI, 2011

This should explain everything you need to know to export your graph in the format you'd like. You can export weighted, unweighted, directed, and undirected graphs. You can set thresholds for edge inclusion, define labels for each vertex, and specify 3D coordinates (which can be the centroids of your regions-of-interest, for example).

The Graph

Let's use an example from neuroscience, since that's what I've been using this for recently. Suppose you have a set of brain regions, R, of size N. For each pair of regions i and j (where i is not j), there may be a projection of axonal fibres of a certain connection strength C(i,j). Let's assume we don't know the directionality of this connection, which means that C(i,j) == C(j,i); in other words, the adjacency matrix is symmetric. This brain network can be described by the adjacency matrix M, which is an N x N square (and symmetric) matrix. Each i,jth element of M contains a value which represents the connection strength between regions i and j; in graph terms, M represents a weighted, undirected graph of size N.

To get this tutorial rolling, let's first create a random graph of size N=20, with an average of number of connections per region K=3 (or, more accurately, a connection probability of 3/20 = 15%), using the script get_random_graph. This will return a symmetric (undirected) random graph:

>> M = get_random_graph(20,3)

M =

     0     1     0     1     0     0     0     0     0     0     1     0     0     0     0     1     0     1     0     0
     1     0     1     0     0     0     0     0     0     0     1     0     0     0     0     0     0     0     0     0
     0     1     0     0     0     1     0     1     0     0     0     1     0     0     0     1     0     0     0     0
     1     0     0     0     0     0     0     0     0     0     0     1     1     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     1     0
     0     0     1     0     0     0     1     0     0     0     0     0     0     0     0     0     1     0     0     0
     0     0     0     0     0     1     0     0     0     0     0     0     1     0     0     0     0     1     0     0
     0     0     1     0     0     0     0     0     0     0     0     1     0     0     0     1     0     0     1     0
     0     0     0     0     0     0     0     0     0     0     0     0     0     1     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     1     0     0     0     1     0     0     0     0
     1     1     0     0     0     0     0     0     0     0     0     0     1     1     0     0     0     0     1     1
     0     0     1     1     0     0     0     1     0     1     0     0     0     0     0     0     0     0     1     0
     0     0     0     1     0     0     1     0     0     0     1     0     0     0     0     0     0     0     1     0
     0     0     0     0     0     0     0     0     1     0     1     0     0     0     0     0     0     0     1     0
     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     1     0     0     0     0
     1     0     1     0     0     0     0     1     0     1     0     0     0     0     1     0     0     0     1     1
     0     0     0     0     0     1     0     0     0     0     0     0     0     0     0     0     0     1     0     1
     1     0     0     0     0     0     1     0     0     0     0     0     0     0     0     0     1     0     0     0
     0     0     0     0     1     0     0     1     0     0     1     1     1     1     0     1     0     0     0     1
     0     0     0     0     0     0     0     0     0     0     1     0     0     0     0     1     1     0     1     0

Your graph will be a bit different of course, since it's randomly generated, but it will be comparable to that above. You'll notice, however, that the values are either zeros or ones. Since we want our edges to be weighted, we take an extra step to create random weights:

>> M = M.*rand(20);

Notably, this weighted network is no longer symmetric. To be thorough, we could take the trouble to mirror the top triangle onto the bottom; however, since the export script (when the 'directed' parameter is set to false) will only use the top triangle (elements above the diagonal) to construct the graph, we don't need to do this. Let's just move on…

To visualize our graph in 3D, we need to define coordinates for our vertices. Ideally, for our brain network example, we'd want these to be the physical centroids of our brain regions. For our tutorial, however, we can just settle for generating random coordinates:

>> coords = rand(20,3)

coords =

    0.8750    0.6524    0.7437
    0.3486    0.5310    0.3020
    0.0419    0.7151    0.0896
    0.1423    0.5048    0.8260
    0.0766    0.4880    0.3896
    0.7405    0.4978    0.7753
    0.4565    0.9360    0.1794
    0.6682    0.3893    0.1094
    0.6992    0.1171    0.9052
    0.5714    0.2404    0.8764
    0.6287    0.6849    0.9998
    0.8778    0.8393    0.8643
    0.6624    0.9701    0.0369
    0.8754    0.2152    0.5447
    0.4675    0.7603    0.9976
    0.1413    0.5841    0.5110
    0.0681    0.4030    0.8735
    0.7142    0.5100    0.0702
    0.3080    0.4956    0.9875
    0.6712    0.6514    0.9227

These will do. We could also now define a list of names for our vertices, corresponding to the names of the regions (as a vector of strings). However, in the absence of this list, the script will use the indices of the regions (1 through N) as labels, and this is fine for our purposes (or mine, anyways). So we are ready to export.

The Export

Having defined our weighted, undirected graph and its coordinates, we can export it with the following command:

>> write_matrix_to_pajek(M,'/some/path/random_graph.net','weighted',true,'directed',false,'coords',coords);

Now, if you open 'random_graph.net' in a text editor, you can see the results:

*vertices 20
 1 "1" 0.875033 0.652421 0.743706
 2 "2" 0.348575 0.531049 0.301953
 3 "3" 0.041921 0.715107 0.089612
 4 "4" 0.142340 0.504811 0.825965
 5 "5" 0.076593 0.487999 0.389587
 6 "6" 0.740527 0.497838 0.775305
 7 "7" 0.456525 0.935976 0.179369
 8 "8" 0.668249 0.389282 0.109361
 9 "9" 0.699246 0.117145 0.905158
 10 "10" 0.571357 0.240424 0.876351
 11 "11" 0.628693 0.684908 0.999793
 12 "12" 0.877764 0.839254 0.864255
 13 "13" 0.662352 0.970145 0.036878
 14 "14" 0.875414 0.215170 0.544682
 15 "15" 0.467517 0.760343 0.997616
 16 "16" 0.141336 0.584103 0.511008
 17 "17" 0.068134 0.402952 0.873512
 18 "18" 0.714242 0.510040 0.070221
 19 "19" 0.307986 0.495644 0.987539
 20 "20" 0.671164 0.651368 0.922713
*edges
 1 2 0.726637
 1 4 0.571413
 1 11 0.519917
 1 16 0.516432
 1 18 0.143951
 2 3 0.666839
 2 11 0.053824
 3 6 0.740008
 3 8 0.678569
 3 12 0.752858
 3 16 0.688933
 4 12 0.110048
 4 13 0.006108
 5 19 0.248952
 6 7 0.260206
 6 17 0.247200
 7 13 0.304298
 7 18 0.497408
 8 12 0.261176
 8 16 0.241937
 8 19 0.830886
 9 14 0.915477
 10 12 0.450963
 10 16 0.612727
 11 13 0.860190
 11 14 0.482507
 11 19 0.380560
 11 20 0.817119
 12 19 0.925869
 13 19 0.740844
 14 19 0.737633
 15 16 0.351098
 16 19 0.510100
 16 20 0.625450
 17 18 0.984532
 17 20 0.346649
 19 20 0.574617

The file is ready to be opened in ModelGUI (or Pajek), which is described in this tutorial. After fiddling around with the scales (hint for 3D: VertexScale=0.05, EdgeCylinderMin=0.005, EdgeWeightScale=0.01), I get a graph that looks like this:

temp_graph_both.png
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License