divide not rectangle plot into subplots within spatstat package in R - r

I have data that contains information about sub-plots with different numbers and their corresponding species types (more than 3 species within each subplot). Every species have X & Y coordinates.
> df
subplot species X Y
1 1 Apiaceae 268675 4487472
2 1 Ceyperaceae 268672 4487470
3 1 Vitaceae 268669 4487469
4 2 Ceyperaceae 268665 4487466
5 2 Apiaceae 268662 4487453
6 2 Magnoliaceae 268664 4487453
7 3 Magnoliaceae 268664 4487453
8 3 Apiaceae 268664 4487456
9 3 Vitaceae 268664 4487458
with these data, I have created ppp for the points of each subplot within a window of general plot (big).
grp <- factor(data$subplot)
win <- ripras(data$X, data$Y)
p.p <- ppp(data$X, data$Y, window = window, marks = grp)
Now I want to divide a plot into equal 3 x 3 sub-plots because there are 9 subplots. The genetal plot is not rectangular looks similar to rombo shape when I plot.
I could use quadrats() funcion as below but it has divided my plot into unequal subplots. Some are quadrat, others are traingle etc which I don't want. I want all the subplots to be equal sized quadrats (divide it by lines that paralel to each sides). Can you anyone guide me for this?
divide <-quadrats(p.patt,3,3)
plot(divide)
Thank you!

Could you break up the plot canvas into 3x3, then run each plot?
> par(mfrow=c(3,3))
> # run code for plot 1
> # run code for plot 2
...
> # run code for plot 9
To return back to one plot on the canvas type
> par(mfrow=c(1,1))

This is a question about the spatstat package.
You can use the function quantess to divide the window into tiles of equal area. If you want the tile boundaries to be vertical lines, and you want 7 tiles, use
B <- quantess(Window(p.patt), "x", 7)
where p.patt is your point pattern.

Related

Color the individuals of a R PCoA plot by groups

Should be a simple question, but I haven't found exactly how to do it so far.
I have a matrix as follow:
sample var1 var2 var3 etc.
1 5 7 3 1
2 0 1 6 8
3 7 6 8 9
4 5 3 2 4
I performed a PCoA using Vegan and plotted the results. Now my problem is that I want to color the samples according to a pre-defined group:
group sample
1 1
1 2
2 3
2 4
How can I import the groups and then plot the points colored according to the group tey belong to? It looks simple but I have been scratching my head over this.
Thanks!
Seb
You said you used vegan PCoA which I assume to mean wcmdscale function. The default vegan::wcmdscale only returns a scores matrix similarly as standard stats::cmdscale, but if you added some special arguments (such as eig = TRUE) you get a full wcmdscale result object with dedicated plot and points methods and you can do:
plot(<pcoa-result>, type="n") # no reproducible example: edit like needed
points(<pcoa-result>, col = group) # no reproducible example: group must be visible
If you have a modern vegan (2.5.x) the following also works:
library(magrittr)
plot(<full-pcoa-result>, type = "n") %>% points("sites", col = group)

Plot time series with confidence intervals in R

Here is a plot of several different time series that I made in R:
I made these using a simple loop:
for(i in 1:ngroups){
x[paste0("Group_",i)] = apply(x[,group == i],1,mean)
}
plot(x$Group_1,type="l",ylim=c(0,300))
for(i in 2:ngroups){
lines(x[paste0("Group_",i)],col=i)
}
I also could have made this plot using matplot. Now, as you can see, each group is the mean of several other columns. What I would like to do is plot the series as in the plot above, but additionally show the range of the underlying data contributing to that mean. For example, the purple line would be bounded by a region shaded light purple. At any given time index, the purple region will extend from the lowest value in the purple group to the highest value (or, say, the 5 to 95 percentiles). Is there an elegant/clever way to do this?
Here is an answer using the graphics package (graphics that come with R). I also try to explain how it is that the polygon (which is used to generate the CI) is created. This can be repurposed to solve your problem, for which I do not have the exact data.
# Values for noise and CI size
s.e. <- 0.25 # standard error of noise
interval <- s.e.*qnorm(0.975) # standard error * 97.5% quantile
# Values for Fake Data
x <- 1:10 # x values
y <- (x-1)*0.5 + rnorm(length(x), mean=0, sd=s.e.) # generate y values
# Main Plot
ylim <- c(min(y)-interval, max(y)+interval) # account for CI when determining ylim
plot(x, y, type="l", lwd=2, ylim=ylim) # plot x and y
# Determine the x values that will go into CI
CI.x.top <- x # x values going forward
CI.x.bot <- rev(x) # x values backwards
CI.x <- c(CI.x.top, CI.x.bot) # polygons are drawn clockwise
# Determine the Y values for CI
CI.y.top <- y+interval # top of CI
CI.y.bot <- rev(y)-interval # bottom of CI, but rev Y!
CI.y <- c(CI.y.top,CI.y.bot) # forward, then backward
# Add a polygon for the CI
CI.col <- adjustcolor("blue",alpha.f=0.25) # Pick a pretty CI color
polygon(CI.x, CI.y, col=CI.col, border=NA) # draw the polygon
# Point out path of polygon
arrows(CI.x.top[1], CI.y.top[1]+0.1, CI.x.top[3], CI.y.top[3]+0.1)
arrows(CI.x.top[5], CI.y.top[5]+0.1, CI.x.top[7], CI.y.top[7]+0.1)
arrows(CI.x.bot[1], CI.y.bot[1]-0.1, CI.x.bot[3], CI.y.bot[3]-0.1)
arrows(CI.x.bot[6], CI.y.bot[6]-0.1, CI.x.bot[8], CI.y.bot[8]-0.1)
# Add legend to explain what the arrows are
legend("topleft", legend="Arrows indicate path\nfor drawing polygon", xjust=0.5, bty="n")
And here is the final result:
I have made a df using some random data.
Here's the df
df
x y
1 1 3.1667912
2 1 3.5301539
3 1 3.8497014
4 1 4.4494311
5 1 3.8306889
6 1 4.7681518
7 1 2.8516945
8 1 1.8350802
9 1 5.8163498
10 1 4.8589443
11 2 0.3419090
12 2 2.7940851
13 2 1.9688636
14 2 1.3475315
15 2 0.9316124
16 2 1.3208475
17 2 3.0367743
18 2 3.2340156
19 2 1.8188969
20 2 2.5050162
When you plot using stat_summary with mean_cl_normal and geom smooth
ggplot(df,aes(x=x,y=y))+geom_point() +
stat_summary(fun.data=mean_cl_normal, geom="smooth", colour="red")
As someone commented, maybe mean_cl_boot was better so I used it.
ggplot(df,aes(x=x,y=y))+geom_point() +
stat_summary(fun.data=mean_cl_boot, geom="smooth", colour="red")
They are indeed a little different. Also you could play with confint parameter depending on your need.

Is there to way to color code different Scatter plot in pairs depending on the number of points in individual plots

I have a data frame(mappedUn) of the structure:
C1 C2 C3 C4 C5 C6
1 1 1 3 1 1
3 3 3 16 3 3
10 NA 10 NA 6 6
11 NA 11 NA 10 11
NA NA NA NA 11 NA
NA NA NA NA 12 NA
note :I have stripped the entries in the above example to fit it here ,also I have replaced the column names to make it simpler
I was wondering if there is a way to color code scatter plots in R, I am using the pairs method to plot different scatter plots, The method I run is :
pairs(mappedUn[1:6])
Here is what I get:
Notice some graphs have two points some have 3 and so on...Is there a way to add different background color to each of the plot in the above graph based on how many point it has ,
for instance 4 points- red, 3-yellow,2 green etc
My ultimate goal is to visually distinguish the plots with high number of common points
The key here is to customize the parameter panel inside pairs(). Try the following to see whether it meets your requirement.
n.notNA <- function(x){
# define the function that returns the number of non-NA values
return(length(x) - sum(is.na(x)))
}
myscatterplot <- function(x, y){
# ll is used for storing the parameters for plotting region
ll <- par("usr")
# bg is used for storing the color (an integer) of the background of current panel, which depends on the number of points. When x and y have different numbers of non-NA values, use the smaller one as the value of bg.
bg <- min(n.notNA(x), n.notNA(y))
# plot a rectangle framework whose dimension and background color are given by ll and bg
rect(ll[1], ll[3], ll[2], ll[4], col = bg)
# fill the rectangle with points
points(x, y)
}
# "panel = myscatterplot" means in each panel, the plot is given by "myscatterplot()" using appropriate combination of variables
pairs(data, panel = myscatterplot)
A related question : R: How to colorize the diagonal panels in a pairs() plot?

Connecting grouped dots/points on a scatter plot based on distance

I have 2 sets of depth point measurements, for example:
> a
depth value
1 2 2
2 4 3
3 6 4
4 8 5
5 16 40
6 18 45
7 20 58
> b
depth value
1 10 10
2 12 20
3 14 35
I want to show both groups in one figure plotted with depth and with different symbols as you can see here
plot(a$value, a$depth, type='b', col='green', pch=15)
points(b$value, b$depth, type='b', col='red', pch=14)
The plot seems okay, but the annoying part is that the green symbols are all connected (though I want connected lines also). I want connection only when one group has a continued data points at 2 m interval i.e. the symbols should be connected with a line from 2 to 8 m (green) and then group B symbols should be connected from 10-14 m (red) and again group A symbols should be connected (green), which means I do NOT want to see the connection between 8 m sample with the 16 m for group A.
An easy solution may be dividing the group A into two parts (say, A-shallow and A-deep) and then plotting A-shallow, B, and A-deep separately. But this is completely impractical because I have thousands of data points with hundreds of groups i.e. I have to produce many depth profiles. Therefore, there has to be a way to program so that dots are NOT connected beyond a prescribed frequency/depth interval (e.g. 2 m in this case) for a particular group of samples. Any idea?
If plot or lines encounters and NA value, it will automatically break the line. Using that, we can insert NA values for missing measurements in your data and that would fix the problem. One way is this
rng<-range(range(a$depth), range(b$depth))
rng<-seq(rng[1], rng[2], by=2)
aa<-rep(NA, length(rng))
aa[match(a$depth, rng)]<-a$value
bb<-rep(NA, length(rng))
bb[match(b$depth, rng)]<-b$value
plot(aa, rng, type='b', col='green', pch=15)
points(bb, rng, type='b', col='red', pch=14)
Which produces
Note that this code assumes that all depth measurements are evenly divisible by 2.
I'm not sure if you really have separate data.frames for all of your groups, but there may be better ways to fill in missing values depending on your real data structure.
We can use the fact that lines will but breaks in when there is a NA, like MrFlick suggests. There might be a simpler way, though:
#Merge the two sets together
all = merge(a,b,by='depth', all=T)
#Plot the lines
plot(all$value.x, all$depth, type='b', col='green', pch=15)
points(all$value.y, all$depth, type='b', col='red', pch=14)

Use a for loop to create several bubble plots with different legend scales in R

I have been trying to make several bubble plots showing the frequency of observations (as a percentage) of several individuals in different sites. Some individuals were found in the same site, but not all. Also the number of locations within each site may vary among individuals. My main problem is that I have more than 3 individuals and more than 3 sites, so I have been trying to come up with a good/fast way of creating this type of bubble plots/legends. I am also having problems with the legend as I need to have a function that will place the legend in the same location when creating a new plot. In the legend I want to show different bubble sizes for each frequency (if possible indicating the value next to the bubble).
Here is an example of my script. Any suggestions or ideas on how to do this will be extremely helpful.
# require libraries
library(maptools)
library(sp)
data<-read.table(text="ind lat long site freq perc
A -18.62303 147.29207 A 449 9.148329258
A -18.6195 147.29492 A 725 14.77180114
A -18.62512 147.3018 A 3589 73.12550937
A -18.62953 147.29422 A 145 2.954360228
B -18.75383 147.25405 B 2 0.364963504
B -18.73393 147.28162 B 1 0.182481752
B -18.62303 147.29207 A 3 0.547445255
B -18.6195 147.29492 A 78 14.23357664
B -18.62512 147.3018 A 451 82.29927007
B -18.62953 147.29422 A 13 2.372262774
C -18.51862 147.39717 C 179 0.863857922
C -18.53281 147.39052 C 20505 98.95757927
C -18.52847 147.40167 C 37 0.178562811",header=TRUE)
# Split data frame for each tag
ind<-data$ind
M<-split(data,ind)
l<-length(M)
### Detection Plots ###
pdf("Plots.pdf",width=11,height=8,paper="a4r")
par(mfrow=c(1,1))
for(j in 1:l){
# locations
new.data<-M[[j]]
site<-as.character(unique(new.data$site))
fname<-paste(new.data$ind[1],sep="")
loc<-new.data[,c("long","lat")]
names(loc)<-c("X", "Y")
coord<-SpatialPoints(loc)
coord1<-SpatialPointsDataFrame(coord,new.data)
# draw some circles with specify radius size
x<-new.data$long
y<-new.data$lat
freq<-new.data$perc
rad<-freq
rad1<-round(rad,1)
title<-paste("Ind","-",fname," / ","Site","-",new.data$site[1],sep="")
# create bubble plot
symbols(x,y,circles=rad1,inches=0.4,fg="black",bg="red",xlab="",ylab="")
points(x,y,pch=1,col="black",cex=0.4)
par(new=T)
# map scale
maps::map.scale(grconvertX(0.4,"npc"),grconvertY(0.1, "npc"),
ratio=FALSE,relwidth=0.2,cex=0.6)
# specifying coordinates for legend
legX<-grconvertX(0.8,"npc")
legY1<-grconvertY(0.9,"npc")
legY2<-legY1-0.001
legY3<-legY2-0.0006
legY4<-legY3-0.0003
# creating the legend
leg<-data.frame(X=c(legX,legX,legX,legX),Y=c(legY1,legY2,legY3,legY4),
rad=c(1000,500,100,25))
symbols(leg$X,leg$Y,circles=leg$rad,inches=0.3,add=TRUE,fg="black",bg="white")
mtext(title,3,line=1,cex=1.2)
mtext("Latitude",2,line=3,padj=1,cex=1)
mtext("Longitude",1,line=2.5,padj=0,cex=1)
box()
}
dev.off()
The first plot is actually Ok, and will only need to have the values of the frequency/perc next to the lengend bubble. However, it does not really work with the others...
You are hardcoding the legend position - make it relative...
legX<-grconvertX(0.8,"npc")
legY1<-grconvertY(0.9,"npc")
# Get the size of the plotting area (measured on the y axis)
ysize <- par()$usr[4]-par()$usr[3]
# Use that to calculate the new positions
legY2<-legY1 - (0.1* ysize)
legY3<-legY1 - (0.2* ysize)
legY4<-legY1 - (0.3* ysize)
This will put the bubbles on the same place on all the plots (in steps of 10% of the plotting area).

Resources