0

The following code produces a directed graph with each node, other than the START and END nodes, having 1 in-degree and 1 out-degree. I'm able to plot the graph in a directed circle as shown here but I would ultimately like to plot this in a straight line. Any help would be greatly appreciated.

library(igraph)
g = graph.data.frame(edges)
V(g)$color = ifelse(V(g)$name == START, "green", ifelse(V(g)$name == END, "red", "light blue"))
plot(g, vertex.frame.color='black', vertex.label.font=1, vertex.label.dist=0.5, vertex.label.cex=0.5, vertex.label=NA,
     vertex.size=ifelse(V(g)$name == START, 2, ifelse(V(g)$name == END, 2, 1)), edge.arrow.size=0.1, edge.width=E(g)$weights/250, layout=layout.circle, 
     main=paste('D6 cell ordering network\n',n_cells,' cells', sep=''))

EDIT: Reproducible example.

START = "D6_EcadSort2250b_TTCACAAGTTTC"
END   = "D6_NoSort2250b_ATTATACGCCCC"

library(TSP)
m <- as.matrix(dist_mat)
S <- which(colnames(m) == START)
E <- which(colnames(m) == END)
atsp <- ATSP(m[-c(S,E), -c(S,E)])
head(atsp)
atsp <- insert_dummy(atsp, label = "S/E")
SE <- which(colnames(atsp) == "S/E")
atsp[SE, ] <- c(m[-c(S,E), S], 0)
atsp[, SE] <- c(m[E, -c(S,E)], 0)

# which method is best?
methods <- c("nearest_insertion", "farthest_insertion", "cheapest_insertion", "arbitrary_insertion", "nn", "repetitive_nn", "two_opt")
tours <- sapply(methods, FUN = function(m) solve_TSP(atsp, method = m), simplify=FALSE)
dotchart(sort(sapply(tours, tour_length)), xlab = "tour length")
best_method = row.names(data.frame((which.min(sort(sapply(tours, tour_length))))))
tour <- solve_TSP(atsp, method=best_method)
path_labels <- c(START, labels(cut_tour(tour, SE)), END)
path_ids <- match(path_labels, colnames(m))

node1 = (path_labels)
node2 = (path_labels[2:length(path_labels)])
length(node2) = length(node1)
edges = data.frame(cbind(node1, node2))
edges = edges[complete.cases(edges),]

weights = m[match(path_labels, rownames(m)),match(path_labels, colnames(m))]
n = 2
n1 = n:ncol(weights)
weights = weights[cbind(seq(n1), n1)]
stopifnot(round(sum(weights), 2) == round(tour_length(tour), 2))
edges$weights = weights

m:

      D6_NoSort2250b_ATTATACGCCCC D6_EcadSort6000b_CCACACCCAGCC D6_EcadSort2250b_CCGATGATTAGC
D6_NoSort2250b_ATTATACGCCCC                         0.000                      1975.317                     1170.9915
D6_EcadSort6000b_CCACACCCAGCC                    1975.317                         0.000                     1977.8852
D6_EcadSort2250b_CCGATGATTAGC                    1170.991                      1977.885                        0.0000
D6_EcadSort2250b_TGTCTGCTTTAG                    1106.524                      1689.820                      962.0281
D6_EcadSort2250b_TTCACAAGTTTC                    1022.989                      1762.582                     1073.0755
                              D6_EcadSort2250b_TGTCTGCTTTAG D6_EcadSort2250b_TTCACAAGTTTC
D6_NoSort2250b_ATTATACGCCCC                       1106.5238                     1022.9888
D6_EcadSort6000b_CCACACCCAGCC                     1689.8195                     1762.5819
D6_EcadSort2250b_CCGATGATTAGC                      962.0281                     1073.0755
D6_EcadSort2250b_TGTCTGCTTTAG                        0.0000                      975.8099
D6_EcadSort2250b_TTCACAAGTTTC                      975.8099                        0.0000
user2117258
  • 515
  • 4
  • 18
  • You should provide some sort of [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input data. Seems odd you have `layout=layout.circle` when you want a line. Have you attempted to explore igraph layouts? – MrFlick May 05 '16 at 15:33
  • @MrFlick, I've edited the original post to include a reproducible example. I have also explored other igraph layouts without luck. None seem to prioritize linearity. – user2117258 May 05 '16 at 16:26
  • For the example posted, layout.auto works. But, this is because of the small number of data points. When we add more we tent to see something that looks like [this](http://i.imgur.com/iXuhq4p.png). – user2117258 May 05 '16 at 16:29
  • 1
    You might want to add `dist_mat` in order to make it reproducible. Also `layout` in `igraph` is just a matrix of coordinates, so you can easily set up a custom layout. – J.R. May 05 '16 at 19:22
  • `dist_mat` is a distance matrix. I've already posted this as `m`. Anything else upstream of `m` is not required for a reproducible example. – user2117258 May 05 '16 at 22:34

1 Answers1

0

This is a bit hacky but seems to work

First I'm creating a very small graph that has a structure similar to how you describe.

g <- graph_from_literal(B-+C, C-+End, Start-+B)
plot(g) # default plot looks nice but not straight

enter image description here

Layouts are simply matrices so we can specify everything in a line. This is in the wrong order.

lo <- cbind(seq(-1,1,length.out = gorder(g)), 0)
plot(g, layout = lo) # wrong order

enter image description here

The last step is to use the ego graph of the start node to get the order

# Find the ordering by using the ego graph of the start node
x <- as.numeric(ego(g, gorder(g), "Start")[[1]])
plot(g, layout = lo[order(x), ])

enter image description here

dougmet
  • 635
  • 4
  • 19