How to incresase igraph distance for each edge in R? - r

I have a CSV file need to draw a graph.
The graph contains nodes and edges.
Therefore, I used the following code to do it.
start.time <- Sys.time()
#Loading Packages
library(igraph)
library(readr)
library(haven)
#import data
df = read.csv('../../Pre_Draw_Graph_for_R.csv', header = TRUE, encoding = 'UTF-8')
#Creating an iGraph Style Edge List
df_Edge_List <- df
#Creating Graph
df_graph = graph.data.frame(df_Edge_List, directed = TRUE)
#df Network: First Try
#Layout Options
set.seed(3500)
layout1 <- layout.fruchterman.reingold(df_graph)
#Node or vertex Options: Color
V(df_graph)$color <- "yellow"
V(df_graph)[degree(df_graph, mode = "in") > 500]$color <- "red"
#Edge Options: Size
E(df_graph)$color <- "grey"
#Plotting
plot(df_graph, vertex.label=NA)
#plot(df_graph)
end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken
I can output the following result, but the result has some problems. It shows that every node is very crowded.
I hope to increase the graph distance, but I used a lot of methods already. I cannot fix the problem. I hope to get the following result, but I cannot do it now. I want to make it clear to see the graph.
I used the following to show dput result.
dput(df_graph, file = "G.R")
Due to the data is too big, I used google link to share it
https://drive.google.com/file/d/1wdF8ZKFde8bDSrFrN9e9KfD3tm6dN_s0/view?usp=sharing
Can anyone help me? Thanks

You can get most of the way to a nice graph with a few simple changes. First, change the vertex labeling to numbers as in your second graph. Also, use layout_components so that the components are separated from each other.
library(igraph)
set.seed(1234)
LOC = layout_components(df_graph)
plot(df_graph, layout=LOC, vertex.label=1:vcount(df_graph))
This is OK, but the arrows are a mess. There are two reasons for that: the arrow heads are too big and most (all?) vertices have loops back to themselves. Let's remove the loops and reduce the size of the arrows.
This looks a lot more useable. If you want anything nicer, you will need to start moving around badly placed vertices by hand. That is a lot more work, but you get a nicer picture.
LOC[ 5,] = c(-1.5,-5)
LOC[ 9,] = c(-3,-2)
LOC[16,] = c(-3,14)
LOC[21,] = c(-3,18)
LOC[25,] = c(9,18)
LOC[29,] = c(-9,18)
LOC[35,] = c(-6,15)
LOC[30,] = c(-9,12)
LOC[31,] = c(-6,18)
LOC[37,] = c(1,14)
LOC[38,] = c(-9,15)
LOC[44,] = c(1,18)
plot(DFGS, layout=LOC, vertex.label=1:vcount(df_graph),
edge.arrow.size = 0.5)
More could be done with the hand-editing, but I will leave that to you.

Related

Is it possible to use `locator()` with plots generated by sf?

I was wondering if it's possible to use the locator() function to create new points with plots generated by plot.sf. I'm sorry but I don't know how to create a reproducible example, so I will do my best to explain my problem.
When I run the following code (clicking, for example, on the centroid of some non-blue regions), the locator() returns the coordinates of the selected points. They have a reasonable value. However, when I plot them, the results are not that accurate (i.e. none of the chosen point lie in the selected region). Can you explain to me what's the problem?
library(sf)
nc = st_read(system.file("gpkg/nc.gpkg", package="sf"), quiet = TRUE)
plot(nc["SID74"], reset = FALSE)
pts <- locator()
pts <- st_sfc(st_multipoint(do.call(cbind, pts)), crs = st_crs(nc))
plot(pts, add = TRUE, pch = 16)
This is an interesting problem; I don't have an answer but I suspect that the issue will be environment related.
I ran your code on Linux (with a small adjustment for target number of points / clicks) and the code behaves as expected. I was able to place three points inside the Mecklenburg (as in Charlotte of Mecklenburg-Strelitz) county.
As locator() seems to use X11 (which is in my case native, but on Windows wrapped in a kind of convoluted fashion) I speculate that your problem may be environment related.
library(sf)
nc = st_read(system.file("gpkg/nc.gpkg", package="sf"), quiet = TRUE)
plot(nc["SID74"], reset = FALSE)
pts <- locator(n = 3) # to speed up the process
pts <- st_sfc(st_multipoint(do.call(cbind, pts)), crs = st_crs(nc))
plot(pts, add = TRUE, pch = 16)

R Indexing a matrix to use in plot coordinates

I'm trying to plot a temporal social network in R. My approach is to create a master graph and layout for all nodes. Then, I will subset the graph based on a series of vertex id's. However, when I do this and layout the graph, I get completely different node locations. I think I'm either subsetting the layout matrix incorrectly. I can't locate where my issue is because I've done some smaller matrix subsets and everything seems to work fine.
I have some example code and an image of the issue in the network plots.
library(igraph)
# make graph
g <- barabasi.game(25)
# make graph and set some aestetics
set.seed(123)
l <- layout_nicely(g)
V(g)$size <- rescale(degree(g), c(5, 20))
V(g)$shape <- 'none'
V(g)$label.cex <- .75
V(g)$label.color <- 'black'
E(g)$arrow.size = .1
# plot graph
dev.off()
par(mfrow = c(1,2),
mar = c(1,1,5,1))
plot(g, layout = l,
main = 'Entire\ngraph')
# use index & induced subgraph
v_ids <- sample(1:25, 15, F)
sub_l <- l[v_ids, c(1,2)]
sub_g <- induced_subgraph(g, v_ids)
# plot second graph
plot(sub_g, layout = sub_l,
main = 'Sub\ngraph')
The vertices in the second plot should match layout of those in the first.
Unfortunately, you set the random seed after you generated the graph,
so we cannot exactly reproduce your result. I will use the same code but
with set.seed before the graph generation. This makes the result look
different than yours, but will be reproducible.
When I run your code, I do not see exactly the same problem as you are
showing.
Your code (with set.seed moved and scales added)
library(igraph)
library(scales) # for rescale function
# make graph
set.seed(123)
g <- barabasi.game(25)
# make graph and set some aestetics
l <- layout_nicely(g)
V(g)$size <- rescale(degree(g), c(5, 20))
V(g)$shape <- 'none'
V(g)$label.cex <- .75
V(g)$label.color <- 'black'
E(g)$arrow.size = .1
## V(g)$names = 1:25
# plot graph
dev.off()
par(mfrow = c(1,2),
mar = c(1,1,5,1))
plot(g, layout = l,
main = 'Entire\ngraph')
# use index & induced subgraph
v_ids <- sort(sample(1:25, 15, F))
sub_l <- l[v_ids, c(1,2)]
sub_g <- induced_subgraph(g, v_ids)
# plot second graph
plot(sub_g, layout = sub_l,
main = 'Sub\ngraph', vertex.label=V(sub_g)$names)
When I run your code, both graphs have nodes in the same
positions. That is not what I see in the graph in your question.
I suggest that you run just this code and see if you don't get
the same result (nodes in the same positions in both graphs).
The only difference between the two graphs in my version is the
node labels. When you take the subgraph, it renumbers the nodes
from 1 to 15 so the labels on the nodes disagree. You can fix
this by storing the node labels in the graph before taking the
subgraph. Specifically, add V(g)$names = 1:25 immediately after
your statement E(g)$arrow.size = .1. Then run the whole thing
again, starting at set.seed(123). This will preserve the
original numbering as the node labels.
The graph looks slightly different because the new, sub-graph
does not take up all of the space and so is stretched to use
up the empty space.
Possible fast way around: draw the same graph, but color nodes and vertices that you dont need in color of your background. Depending on your purposes it can suit you.

Reduce file size of a plot (R) (plotly)

I've created a map in R using ggplotly. To create a link, it needs to be 524kb or under, but it currently is 1.2Mb. Are there any good ways of reducing file size so I can export it? Or is this totally unrealistic?
If your map has polygons, consider rmapshader::ms_simplify(), which uses the Visvalingam algorithm to reduce the number of points used to construct a polygon.
Here's a reproducible example:
> p <- raster::shapefile(system.file("external/lux.shp", package="raster")) # load data
> p2 <- rmapshaper::ms_simplify(p, keep_shapes = TRUE) # simplify polygons
Now visualize the result:
> par(mfrow = c(1,2))
> plot(p, main = paste("before:", object.size(p), "bytes"))
> plot(p2, main = paste("after:", object.size(p2), "bytes"))
> dev.off()
You can edit the default settings on the keep argument, lowering the number of points to retain, and thus further reducing your object size. This comes at the cost of a coarser image.

Dendrogram in R by complete linkage not spaced properly

I am a newbie with R. To speak in a very understandable way, What I want to achieve is a dendrogram like this
What I want the dendrogram to look like
and how I get it is like this,
How I am getting it
This is the code, that I ran,
tb <- read.csv("COM_PDT.csv", row.names = 1)
> d = as.dist(tb)
> hc.c <- hclust(d)
> plot(hc.c, hang = -1)
And here is the data set,
,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48
1,,0,0,0,0,0,0,0,3,1,4,0,4,0,3,0,0,4,0,0,0,4,0,0,1,1,4,3,0,3,3,0,1,0,4,4,0,0,0,0,1,0,3,0,0,0,4,1
2,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,0,0,0,0,0,2,0,0,0,0,0,2,3,1,0,0,0,1,0,0,0,0
3,0,0,,2,0,0,1,1,0,0,0,0,0,1,0,1,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,1,0,0,0,0,0,1
4,0,0,2,,1,1,1,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0,1,1,0,1,0,1,1,0,1,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1
5,0,0,0,1,,3,0,0,0,1,0,1,0,0,1,0,2,0,2,1,1,0,3,2,3,0,0,1,2,1,1,1,2,2,0,0,2,1,1,1,1,2,0,0,2,2,0,0
6,0,0,0,1,3,,0,1,0,2,0,2,0,1,1,1,3,0,3,1,1,0,4,2,3,0,0,1,3,1,1,0,3,3,0,0,2,0,0,0,2,1,0,0,3,3,0,1
7,0,0,1,1,0,0,,3,0,0,0,2,0,3,0,2,1,0,0,1,3,0,0,2,0,1,0,0,1,0,0,0,0,1,0,0,2,0,0,0,1,1,0,0,1,1,0,2
8,0,0,1,1,0,1,3,,0,1,0,3,0,4,0,3,2,0,1,1,2,0,1,1,0,1,0,0,2,0,0,0,1,2,0,0,1,0,0,0,2,1,0,0,2,2,0,3
9,3,0,0,0,0,0,0,0,,1,3,0,3,0,2,0,0,3,0,0,0,3,0,0,0,1,3,2,0,2,2,0,1,0,3,3,0,0,0,0,1,0,3,0,0,0,3,1
10,1,0,0,1,1,2,0,1,1,,1,1,1,1,1,1,1,1,1,0,0,1,2,0,1,0,1,2,1,2,2,0,3,1,1,1,0,0,0,0,2,1,1,1,1,1,1,2
11,4,0,0,0,0,0,0,0,3,1,,0,4,0,3,0,0,4,0,0,0,4,0,0,1,1,4,3,0,3,3,0,1,0,3,4,0,0,0,0,1,0,3,0,0,0,4,1
12,0,0,0,0,1,2,2,3,0,1,0,,0,3,1,2,3,0,2,2,3,0,2,2,1,0,0,0,3,0,0,0,2,3,0,0,2,0,0,0,3,0,0,0,3,3,0,2
13,4,0,0,0,0,0,0,0,3,1,4,0,,0,3,0,0,4,0,0,0,4,0,0,1,1,4,3,0,3,3,0,1,0,3,4,0,0,0,0,1,0,3,0,0,0,4,1
14,0,0,1,1,0,1,3,4,0,1,0,3,0,,0,3,2,0,1,1,2,0,1,1,0,1,0,0,2,0,0,0,1,2,0,0,1,0,0,0,2,1,0,0,2,2,0,3
15,3,0,0,0,1,1,0,0,2,1,3,1,3,0,,0,1,3,1,1,1,3,1,1,2,1,3,2,1,2,2,0,2,1,2,3,1,0,0,0,2,0,2,0,1,1,3,1
16,0,0,1,1,0,1,2,3,0,1,0,2,0,3,0,,2,0,1,2,1,0,1,1,0,2,0,0,2,0,0,0,1,2,0,0,1,0,0,0,2,1,0,0,2,2,0,3
17,0,0,0,0,2,3,1,2,0,1,0,3,0,2,1,2,,0,3,2,2,0,3,3,2,0,0,0,4,0,0,0,2,4,0,0,3,0,0,0,3,0,0,0,4,4,0,2
18,4,0,0,0,0,0,0,0,3,1,4,0,4,0,3,0,0,,0,0,0,4,0,0,1,1,4,3,0,3,3,0,1,0,3,4,0,0,0,0,1,0,3,0,0,0,4,1
19,0,0,0,0,2,3,0,1,0,1,0,2,0,1,1,1,3,0,,1,1,0,3,2,2,0,0,0,3,0,0,1,2,3,0,0,2,1,0,1,2,0,0,0,3,3,0,1
20,0,0,0,1,1,1,1,1,0,0,0,2,0,1,1,2,2,0,1,,2,0,1,2,1,1,0,0,2,0,0,0,1,2,0,0,2,0,0,0,2,0,0,0,2,2,0,1
21,0,0,0,0,1,1,3,2,0,0,0,3,0,2,1,1,2,0,1,2,,0,1,3,1,0,0,0,2,0,0,0,1,2,0,0,3,0,0,0,2,0,0,0,2,2,0,1
22,4,0,0,0,0,0,0,0,3,1,4,0,4,0,3,0,0,4,0,0,0,,0,0,1,1,4,3,0,3,3,0,1,0,3,4,0,0,0,0,1,0,3,0,0,0,4,1
23,0,0,0,1,3,4,0,1,0,2,0,2,0,1,1,1,3,0,3,1,1,0,,2,3,0,0,1,3,1,1,0,3,3,0,0,2,0,0,0,2,1,0,0,3,3,0,1
24,0,0,0,0,2,2,2,1,0,0,0,2,0,1,1,1,3,0,2,2,3,0,2,,2,0,0,0,3,0,0,0,1,3,0,0,4,0,0,0,2,0,0,0,3,3,0,1
25,1,0,0,1,3,3,0,0,0,1,1,1,1,0,2,0,2,1,2,1,1,1,3,2,,0,1,2,2,2,2,0,2,2,0,1,2,0,0,0,1,1,0,0,2,2,1,0
26,1,0,1,1,0,0,1,1,1,0,1,0,1,1,1,2,0,1,0,1,0,1,0,0,0,,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,1,1
27,4,0,0,0,0,0,0,0,3,1,4,0,4,0,3,0,0,4,0,0,0,4,0,0,1,1,,3,0,3,3,0,1,0,3,4,0,0,0,0,1,0,3,0,0,0,4,1
28,3,0,0,1,1,1,0,0,2,2,3,0,3,0,2,0,0,3,0,0,0,3,1,0,2,0,3,,0,4,4,0,2,0,2,3,0,0,0,0,1,1,2,0,0,0,3,1
29,0,0,0,0,2,3,1,2,0,1,0,3,0,2,1,2,4,0,3,2,2,0,3,3,2,0,0,0,,0,0,0,2,4,0,0,3,0,0,0,3,0,0,0,4,4,0,2
30,3,0,0,1,1,1,0,0,2,2,3,0,3,0,2,0,0,3,0,0,0,3,1,0,2,0,3,4,0,,4,0,2,0,2,3,0,0,0,0,1,1,2,0,0,0,3,1
31,3,0,0,1,1,1,0,0,2,2,3,0,3,0,2,0,0,3,0,0,0,3,1,0,2,0,3,4,0,4,,0,2,0,2,3,0,0,0,0,1,1,2,0,0,0,3,1
32,0,2,0,0,1,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,4,3,3,0,1,0,0,0,0,0,0
33,1,0,0,1,2,3,0,1,1,3,1,2,1,1,2,1,2,1,2,1,1,1,3,1,2,0,1,1,2,1,2,0,,2,1,1,1,0,0,0,3,1,1,0,2,2,1,2
34,0,0,0,0,2,3,1,2,0,1,0,3,0,2,1,2,4,0,3,2,2,0,3,3,2,0,0,0,4,0,0,0,2,,0,0,3,0,0,0,3,0,0,0,4,4,0,2
35,4,0,0,0,0,0,0,0,3,1,4,0,4,0,3,0,0,4,0,0,0,4,0,0,1,1,4,3,0,3,3,0,1,0,,4,0,0,0,0,1,0,3,0,0,0,4,1
36,4,0,0,0,0,0,0,0,3,1,4,0,4,0,3,0,0,4,0,0,0,4,0,0,1,1,4,3,0,3,3,0,1,0,3,,0,0,0,0,1,0,3,0,0,0,4,1
37,0,0,0,0,2,2,2,1,0,0,0,2,0,1,1,1,3,0,2,2,3,0,2,4,2,0,0,0,3,0,0,0,1,3,0,0,,0,0,0,2,0,0,0,3,3,0,1
38,0,2,0,0,1,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,4,0,0,0,0,0,,3,3,0,1,0,0,0,0,0,0
39,0,3,0,0,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,0,3,0,0,0,0,0,3,,2,0,1,0,0,0,0,0,0
40,0,1,0,0,1,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,3,0,0,0,0,0,3,2,,0,2,0,0,0,0,0,0
41,1,0,0,0,1,2,1,2,1,2,1,3,1,2,2,2,3,1,2,2,2,1,2,2,1,0,1,1,3,1,1,0,3,3,1,1,2,0,0,0,,0,1,0,3,3,1,3
42,0,0,1,2,2,1,1,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,2,0,,0,0,0,0,0,1
43,3,0,0,0,0,0,0,0,3,1,3,0,3,0,2,0,0,3,0,0,0,3,0,0,0,1,3,2,0,2,2,0,1,0,3,3,0,0,0,0,1,0,,0,0,0,3,1
44,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,0,0,0,0
45,0,0,0,0,2,3,1,2,0,1,0,3,0,2,1,2,4,0,3,2,2,0,3,3,2,0,0,0,4,0,0,0,2,4,0,0,3,0,0,0,3,0,0,0,,4,0,2
46,0,0,0,0,2,3,1,2,0,1,0,3,0,2,1,2,4,0,3,2,2,0,3,3,2,0,0,0,4,0,0,0,2,4,0,0,3,0,0,0,3,0,0,0,4,,0,2
47,4,0,0,0,0,0,0,0,3,1,4,0,4,0,3,0,0,4,0,0,0,4,0,0,1,1,4,3,0,3,3,0,1,0,3,4,0,0,0,0,1,0,3,0,0,0,,1
48,1,0,1,1,0,1,2,3,1,2,1,2,1,3,1,3,2,1,1,1,1,1,1,1,0,1,1,1,2,1,1,0,2,2,1,1,1,0,0,0,3,1,1,0,2,2,1,
Please help me to get a clean dendrogram that is neatly spaced and the end nodes properly at the floor of the graph!
I think you need to write dist(tb), not as.dist(tb). That will help the branching appearance of how it is being plotted. Change hang = to adjust the labeling, though initially I haven't been able to produce exactly how the labels are in your desired plot.
d = dist(tb)
hc.c <- hclust(d)
plot(hc.c, hang = -1)

connecting a set of points with lines in R

At present, I generate a figure using the following script
dat <- matrix(runif(1000*99),99,1000)
dat <- rbind(rep(0.1,1000),dat)
out <- cmdscale(dist(dat),k = 2)
plot(out)
points(out[1,1],out[1,2],col = "red")
Based on the above figure, I want to connect that red point with other points, how to do that?
If you want to connect all the points to that red point, you could try...
segments(out[1,1],out[1,2],out[,1],out[,2])
Adjusting the order of the printing and the graphical characteristics could make it a little easier to look at too:
dat <- matrix(runif(1000*99),99,1000)
dat <- rbind(rep(0.1,1000),dat)
out <- cmdscale(dist(dat),k = 2)
plot(out,type="n")
segments(out[1,1],out[1,2],out[,1],out[,2],col="#cccccc")
points(out,col="black",pch=20)
points(out[1,1],out[1,2],col = "red",pch=20)

Resources