R: Draw arrows in ggplot2 based on loop - r

I have a dataset as follows:
i <- data.scores
i
NMDS1 NMDS2
Plot_1_O -0.1716069847 -1.177471624
Plot_2_O -0.2452065424 -0.978276228
Plot_3_O 0.3885298355 -0.578810975
... ... ...
Plot_64_O 0.7976712787 -0.187241724
Plot_1_N -0.4044221768 -0.239157686
Plot_2_N 0.2539782304 0.197509348
Plot_3_N 0.3163483600 -0.130876763
... ... ...
Plot_64_N 0.6346501475 0.265873211
As you (may or may not) see, it's vegetational plot-data on 64 different plots, taken at several points in time (hence the "O"/"N" for "Old" and "New"). I've ran an NMDS via vegan's metaMDS() and got a plot showing my results. I've also calculated a fit via env_fit() and relevant environmental data. The finished plot is fine, but I wanted to add arrows between the pairs of old and new survey data. I used a loop to do so:
for (j in 1:64){
k <- j+64
arrows(data.scores$NMDS1[j], data.scores$NMDS2[j],
data.scores$NMDS1[k], data.scores$NMDS2[k], length = 0.1, lwd=2)
}
The resulting plot looks like this: NMDS-Plot
The black symbols show the old plots, the red symbols the new ones respectively.
For better aesthetics I re-drew the plot in ggplot2, and everything worked perfectly fine, until I had to draw those arrows again. I cannot use a loop within the ggplot2-command, and I do not know how draw all of those arrows at once. I tried something like this:
geom_segment(data=i, aes(x=i$NMDS1[1:64], xend=i$NMDS1[65:128],
y=i$NMDS2[1:64], yend=i$NMDS2[65:128]),
arrow = arrow(length = unit(0.5, "cm")), colour="red",
inherit.aes=FALSE, lwd=2)
but it does not draw any arrows at all, not even a single one. Removing the column-specification does not help either, and I doubt I would get all the respective arrows at once. Can anybody help?

I found a solution: Based on my last line of code where I tried to draw the arrows geom_segment(data=i, aes(x=i$NMDS1[1:64], xend=i$NMDS1[65:128], y=i$NMDS2[1:64], yend=i$NMDS2[65:128]), arrow = arrow(length = unit(0.5, "cm")), colour="red", inherit.aes=FALSE, lwd=2) I saved the plot as an object called "Plot_Final" and tried this:
for (j in 1:64){ #j=1
k <- j+64
Plot_Final <- Plot_Final + geom_segment(data=i, x=i$NMDS1[j], xend=i$NMDS1[k], y=i$NMDS2[j], yend=i$NMDS2[k], arrow = arrow(length = unit(0.3, "cm")), colour="black", inherit.aes=FALSE, lwd=0.1)
}
By removing the aes()-argument I finally got my arrows pointing out the plot-pairs within my ggplot2-plot. Thank you anyway!

Related

R drawing a barcode by giving the explicite position where to draw the black lines

Is there any function to draw a bar-code with R, which takes the height (or say the width = the number of lines) and the position where to draw a black lines.
Thanks for your help.
David.
You can print bar codes with the zintr package. For this to work, you'll need to install zint and then zintr. See the installation instructions on the zintr development site.
Then, to create a bar code:
library(zintr)
barcode_print("3.14159265", "pi.png")
If instead you want to draw a bar code, given a series of widths for each segment, here's some fake data for a demonstration using ggplot2. Real bar codes can have multiple segments for a given character, and the example below doesn't capture this. It just gives you an idea of how to draw the segments if you know their locations and widths.
library(ggplot2)
barcode = function(x, w, num) {
bc = data.frame(x, w, num)
bc$xpos = seq(min(bc$x)+0.15, max(bc$x)-0.15, length=nrow(bc))
ggplot(bc) +
geom_rect(aes(xmin=x - 0.5*w, xmax=x+0.5*w, ymin=0, ymax=1),
show.legend=FALSE, fill="black") +
geom_text(aes(label=num, x=xpos, y=-0.07)) +
coord_fixed(0.5) +
theme_void()
}
Then, to run the function:
barcode(x=cumsum(0 + runif(12, 0.05, 0.1)),
w=runif(12,0.01,0.05),
num=sample(0:9, 12, replace=TRUE))

ggpairs() correlation values without gridlines

I have this code that generates the plot below.
library(ggplot2)
library(GGally)
data(iris)
ggpairs(data = iris[, 1:4], axisLabels = "none", switch = "both")
I'd like to do three things with this plot: 1) remove the gridlines in the correlation windows; 2) increase font size of the x-y axes labels; and 3) make these label-backgrounds white (instead of gray). The first question was addressed about 4 years ago here and here, and it seems one would need to either rebuild GGally package, or use a custom code from GitHub. Both options are pretty heavy for a newbie like me, and I am wondering if someone has figured out an easier method by now. I have not found my 2nd and 3rd questions addressed anywhere.
Thanks.
The first request can be handled by:
+theme(panel.grid.minor = element_blank(),
panel.grid.major = element_blank())
The size of the axis labels (which are really in "strips" can be handled with this additional arguemnt to theme:
... , strip.text = element_text(size = 5))

How do I exclude parameters from an RDA plot

I'm still relatively inexperienced manipulating plots in R, and am in need of assistance. I ran a redundancy analysis in R using the rda() function, but now I need to simplify the figure to exclude unnecessary information. The code I'm currently using is:
abio1516<-read.csv("1516 descriptors.csv")
attach(abio1516)
bio1516<-read.csv("1516habund.csv")
attach(bio1516)
rda1516<-rda(bio1516[,2:18],abio1516[,2:6])
anova(rda1516)
RsquareAdj(rda1516)
summary(rda1516)
varpart(bio1516[,2:18],~Distance_to_source,~Depth, ~Veg._cover, ~Surface_area,data=abio1516)
plot(rda1516,bty="n",xaxt="n",yaxt="n",main="1516; P=, R^2=",
ylab="Driven by , Var explained=",xlab="Driven by , Var explained=")
The produced plot looks like this:
Please help me modify my code to: exclude the sites (sit#), all axes, and the internal dashed lines.
I'd also like to either expand the size of the field, or move the vector labels to all fit in the plotting field.
updated as per responses, working code below this point
plot(rda,bty="n",xaxt="n",yaxt="n",type="n",main="xxx",ylab="xxx",xlab="xxx
Overall best:xxx")
abline(h=0,v=0,col="white",lwd=3)
points(rda,display="species",col="blue")
points(rda,display="cn",col="black")
text(rda,display="cn",col="black")
Start by plotting the rda with type = "n" which generates an empty plot to which you can add the things you want. The dotted lines are hard coded into the plot.cca function, so you need either make your own version, or use abline to hide them (then use box to cover up the holes in the axes).
require(vegan)
data(dune, dune.env)
rda1516 <- rda(dune~., data = dune.env)
plot(rda1516, type = "n")
abline(h = 0, v = 0, col = "white", lwd = 3)
box()
points(rda1516, display = "species")
points(rda1516, display = "cn", col = "blue")
text(rda1516, display = "cn", col = "blue")
If the text labels are not in the correct position, you can use the argument pos to move them (make a vector as long as the number of arrows you have with the integers 1 - 4 to move the label down, left, up, or right. (there might be better solutions to this)

ggplot2 fix geom_points position

Im developing a function that uses ggplot2 to create multiple graphs that compares two set of points representing shapes.
ref = matrix(c(1,3,1,3,2,2,4,4),nrow=4, ncol=2)
ref<-data.frame(x=ref[,1], y=ref[,2])
shapes<-list()
shapes[[1]]<-matrix(c(1.5,2.9,1.4,3.1,2.2,2.3,4.5,3.5),nrow=4, ncol=2)
shapes[[2]]<-matrix(c(0.5,3.9,1.1,3.1,1.8,2,4.5,3.5),nrow=4, ncol=2)
shapes[[3]]<-matrix(c(1.8,3.2,1,3.5,2.2,2.3,4.5,3.5),nrow=4, ncol=2)
newplots<-list()
for(i in 1:length(shapes)){
target<-shapes[[i]]
vari<-data.frame(x=target[,1], y=target[,2])
newplots[[i]]<-ggplot(ref,aes(x = x,y = y)) + geom_point(size=2,color="red")+coord_fixed()+
geom_point(data=vari,aes(x=x,y=y),color="black",size=3)
}
newplots[[1]]
newplots[[2]]
newplots[[3]]
newplots[[4]]
The problem is that the reference points seem to "move" from plot to plot when they suppose to stay in the same place.
When you say 'move' are you referring to the graph scaling changing? I ran the code and that's the only change I noticed. If so- you can simply add something like:
+ xlim(1, 4) + ylim(2,5)
in the the loop after the ggplot.

How can I overlay two dense scatter plots so that I can see the outlines of each in R or Matlab?

See this example
This was created in matlab by making two scatter plots independently, creating images of each, then using the imagesc to draw them into the same figure and then finally setting the alpha of the top image to 0.5.
I would like to do this in R or matlab without using images, since creating an image does not preserve the axis scale information, nor can I overlay a grid (e.g. using 'grid on' in matlab). Ideally I wold like to do this properly in matlab, but would also be happy with a solution in R. It seems like it should be possible but I can't for the life of me figure it out.
So generally, I would like to be able to set the alpha of an entire plotted object (i.e. of a matlab plot handle in matlab parlance...)
Thanks,
Ben.
EDIT: The data in the above example is actually 2D. The plotted points are from a computer simulation. Each point represents 'amplitude' (y-axis) (an emergent property specific to the simulation I'm running), plotted against 'performance' (x-axis).
EDIT 2: There are 1796400 points in each data set.
Using ggplot2 you can add together two geom_point's and make them transparent using the alpha parameter. ggplot2 als adds up transparency, and I think this is what you want. This should work, although I haven't run this.
dat = data.frame(x = runif(1000), y = runif(1000), cat = rep(c("A","B"), each = 500))
ggplot(aes(x = x, y = y, color = cat), data = dat) + geom_point(alpha = 0.3)
ggplot2 is awesome!
This is an example of calculating and drawing a convex hull:
library(automap)
library(ggplot2)
library(plyr)
loadMeuse()
theme_set(theme_bw())
meuse = as.data.frame(meuse)
chull_per_soil = ddply(meuse, .(soil),
function(sub) sub[chull(sub$x, sub$y),c("x","y")])
ggplot(aes(x = x, y = y), data = meuse) +
geom_point(aes(size = log(zinc), color = ffreq)) +
geom_polygon(aes(color = soil), data = chull_per_soil, fill = NA) +
coord_equal()
which leads to the following illustration:
You could first export the two data sets as bitmap images, re-import them, add transparency:
library(grid)
N <- 1e7 # Warning: slow
d <- data.frame(x1=rnorm(N),
x2=rnorm(N, 0.8, 0.9),
y=rnorm(N, 0.8, 0.2),
z=rnorm(N, 0.2, 0.4))
v <- with(d, dataViewport(c(x1,x2),c(y, z)))
png("layer1.png", bg="transparent")
with(d, grid.points(x1,y, vp=v,default="native",pch=".",gp=gpar(col="blue")))
dev.off()
png("layer2.png", bg="transparent")
with(d, grid.points(x2,z, vp=v,default="native",pch=".",gp=gpar(col="red")))
dev.off()
library(png)
i1 <- readPNG("layer1.png", native=FALSE)
i2 <- readPNG("layer2.png", native=FALSE)
ghostize <- function(r, alpha=0.5)
matrix(adjustcolor(rgb(r[,,1],r[,,2],r[,,3],r[,,4]), alpha.f=alpha), nrow=dim(r)[1])
grid.newpage()
grid.rect(gp=gpar(fill="white"))
grid.raster(ghostize(i1))
grid.raster(ghostize(i2))
you can add these as layers in, say, ggplot2.
Use the transparency capability of color descriptions. You can define a color as a sequence of four 2-byte words: muddy <- "#888888FF" . The first three pairs set the RGB colors (00 to FF); the final pair sets the transparency level.
AFAIK, your best option with Matlab is to just make your own plot function. The scatter plot points unfortunately do not yet have a transparency attribute so you cannot affect it. However, if you create, say, most crudely, a bunch of loops which draw many tiny circles, you can then easily give them an alpha value and obtain a transparent set of data points.

Resources