Inconsistencies between tkplot.coords and plot() coordinates in iGraph plots - r

I'm making a network plot in R using iGraph. I first plot it using tkplot() so that I can manually reposition some of the nodes. Then I capture the new coordinates and then insert those in the plot function to replot the graph along with additional adjustments (changing the opacity of the nodes).
The problem is that even when using the tkplot.coords coordinates, the second graph doesn't look like the tkplot. Instead, some of the arrow heads appear in the middle of the edge rather than at the end, and the nodes are tightly clustered and overlapping, even though that isn't the case with the tkplot. Any suggestions for how I can get the plot() function to exactly mimic the plot produced using tkplot()?
I am using R Studio, so I am wondering if there is a conversion issue with that.
My simplified code is as follows:
Net1 <- graph.data.frame(myedgedata, vertices=nodeslist, directed=TRUE)
g <- graph.adjacency(get.adjacency(Net1), weighted = TRUE)
E(g)$weight <- E(g)$weight+1
tkplot(g)
coords <- tkplot.getcoords(1)
plot(g, edge.width=E(g)$weight, vertex.color = adjustcolor(nodeslist$colors, alpha=.5), layout=coords)

Related

rgl 3D scatterplot - controlling size of spheres from 4th dimension (bubble plot)

I am working on a 3D scatter plot using rgl package in R, with multiple colors for different series. I was wondering if there would be a way to plot a 4th dimension by controlling the size of spheres.
I know it's possible with plotly ("bubble plot") : https://plot.ly/r/3d-scatter-plots/, but Plotly starts to flicker when dealing with lots of datapoints. Can the same result be achieved using Rgl?
set.seed(101)
dd <- data.frame(x=rnorm(100),y=rnorm(100),z=rnorm(100),
c=rnorm(100),s=rnorm(100))
Scaling function (I tweaked to keep the values strictly in (0,1), don't know if that's really necessary):
ss <- function(x) scale(x,center=min(x)-0.01,scale=diff(range(x))+0.02)
library(rgl)
Define colours (there may be a better way to do this ...)
cvec <- apply(colorRamp(c("red","blue"))(ss(dd$c))/255,1,
function(x) rgb(x[1],x[2],x[3]))
The picture (need type="s" to get spheres)
with(dd,plot3d(x,y,z,type="s",radius=ss(s), col=cvec))

linear graph with specific scale for nodes in ggraph R

I'm experimenting with the outstanding ggraph library to depict some really-hard to depict interrelationships for a scientific work. Specifically, I want to show SNP-SNP interactions in a genetic locus. It would be very nice if I plotted the interactions as curved nodes of a graph, where the SNPs are positioned in a linear fashion according to their genetic positions. The geom_edge_arc() aesthetics from the ggraph library would be ideal. However, I cannot put the nodes in an order according to the positions.
Here is an example
library(igraph)
library(tidyverse)
library(ggraph)
set.seed(10)
nodes <- tibble(nodes = paste("SNP",seq(1:10)), pos = sample(c(10000:20000),10))
edges <- expand.grid(nodes$nodes,nodes$nodes) %>%
mutate(interaction = rnorm(100)) %>%
filter(abs(interaction)>1)
gr <- graph_from_data_frame(edges, vertices = nodes)
ggraph(gr, 'linear', circular=F) +
geom_edge_arc(aes(edge_width=interaction))
The nodes are evenly spaced here, as "factors". However, I wanted to place them on the x coordinate as specified by the pos variable (which in turn becomes an attribute of the nodes). Adding + geom_node_point(aes(x=pos))to the ggplot object doesn't result in a correct rendering. I could probably do the plot with "basic" ipgraph too, but I like ggraph and ggplot2, and it would be an elegant and easy way to plot with this.
Kind regards, and thanks in advance,
Robert
Not sure if this is still relevant, but there are two ways to solve this.
As noted by #axeman, you can use the manual layout, and basically pass the x and y coordinates to it:
ggraph(gr,
layout = 'manual',
node.position = data_frame(y = rep(0, length(nodes$pos)), x = nodes$pos)) +
geom_edge_arc(aes(edge_width=interaction))
The othe way is to overrride the x aes inside geom_edge_arc. To be able to pass a node attribute to an aes we need to use geom_edge_arc2:
ggraph(gr, 'linear', circular=F) +
geom_edge_arc2(aes(edge_width=interaction, x = node.pos))
Created on 2018-05-30 by the reprex package (v0.2.0).

increasing the distance between igraph nodes

I have a graph that I have produced using igraph. I'd like to spread out the nodes. The only way I have found so far to do this is to scale the layout and force the plot command to not rescale.
png("kmeansColouredNetwork.png", width=1200,height = 1000)
col=c("yellow", "saddlebrown", "brown1","chartreuse2", "chocolate1","darkorange" ,"deepskyblue1", "hotpink1","plum2")
for(i in 1:9){
V(graph)$cluster[which(V(graph)$name %in% kmeans[,i])]<-col[i]
}
V(graph)$color=V(graph)$cluster
coords <- layout.fruchterman.reingold(graph)*0.5
plot(graph, layout = coords, vertex.label=NA, rescale=FALSE, vertex.size=degree(graph)*.25,vertex.color=V(graph)$cluster)
labels = paste("cluster:", 1:length(colours))
legend("left",legend=labels, col=col, pch=16, title="K means clustered subgroups")
dev.off()
If I don't rescale, the central highly connected nodes clump together and I get a graph like this, where the patterns in the body of the graph are impossible to discern:
On the other hand, if I tell the plot command not to rescale, then I get this :
where the patterns are discernible, but half the graph is off the plot. It's not a matter of plot size as if I increase the dimensions of the png, it still centres the graph off the edge of the plot.
It's not a matter of the layout - I've tried fruchterman.reingold, layout_nicely, reingold.tilford, layout.circle, layout random, the same thing happens.
There apparently used to be a variable to set a repulsion factor between nodes, but that appears to be deprecated.
How does one spread the nodes of the graph out or rescale and recenter the plot?
Option 1: make the vertices smaller
node.size= c(10,10,10)
plot(net, vertex.size=node.size*0.25)
Option 2 (in case the distances between the vertices are not important to you):
# Use the tkplot option to edit your graph in GUI
tkplot (net)
Note: tkplot outputs the graph as eps. If you want to edit it further or export it to pdf I suggest using inkscape (I use it for all my graph editing - just save the graph as pdf in RStudio and edit it in inkscape).
For the case of eps if you are on a windows machine you will need to tweak inkscape to open this format. A very short and simple process which is detailed here:
I just found the below answer on StackOverflow:
igraph axes xlim ylim plot incorrectly
Basically, you can set ylim and xlim and asp. You can set which part of the graph to display (as usual with xlim and ylim) and if the two axis are dependent on each other.
plot(g, rescale = FALSE, ylim=c(1,4),xlim=c(-17,24), asp = 0)

How to change vertice labels on graph in bnlearn

I need help changing the vertex labels on graphs produced using bnlearn.
First, I run the program to get an undirected graph. When I plot the graph with plot(data) the vertices are labelled with "V1,V2,V3...". Instead of this I want to plot them with their real labels.
The default plot should have the variable names as the node labels - you will need to share some code to show why this is not so. However, below is a method to manually change the node labels.
library(bnlearn)
library(Rgraphviz)
m <- hc(learning.test)
par(mfrow=c(1,2))
#default plot
g <- graphviz.plot(m)
# change labels
z <- paste0("newlab_", letters[1:numNodes(g)])
names(z) <- nodes(g)
nAttrs <- list()
nAttrs$label <- z
# updated plots
plot(g, nodeAttrs=nAttrs)
For more info on Rgraphviz see How To Plot A Graph Using Rgraphviz, Jeff Gentry

Save the orientation of a RGL plot3d() plot

I have a 3D plot using RGL. I would like to make identical plots using color to highlight the distribution of some variable. To do this I would like to have identical plots, how do I find and set the orientation of a plot?
Once I make a preliminary plot, I move it around to find a nice display angle and I would like to save that angle and incorporate it into future plotting scripts. Anyone have a suggestion on how to do this?
library(rgl)
plot3d(iris)
#play with the plot to find a good angle
#save the angle for future plots
Ben's comment basically answers your question; this just applies expand.dots to what he wrote ;)
## In an inital session:
library(rgl)
plot3d(iris)
## Now move the image around to an orientation you like
## Save RGL parameters to a list object
pp <- par3d(no.readonly=TRUE)
## Save the list to a text file
dput(pp, file="irisView.R", control = "all")
.......
## Then, in a later session, to recreate the plot just as you had it:
library(rgl)
pp <- dget("irisView.R")
plot3d(iris)
par3d(pp)

Resources