R: Combining several lines and points in one polar plot - r

I have data from several sources describing an y value in a 360 degrees space but I cannot plot them together with a fitted spline on a single polar plot.
Here's some simulated data:
# Data for test
set.seed(35)
sim1 <- cbind(rnorm(6,0),seq(0,359,359/5))
sim2 <- cbind(rnorm(9,0),seq(0,359,359/8))
sim3 <- cbind(rnorm(7,0),seq(0,359,359/6))
If not doing a polar plot my procedure would be as follows:
# Create spline for points
total <- rbind(sim1,sim2,sim3)
fit= smooth.spline(total[,2],total[,1], cv=T)
# Classic solution if not polar plot
plot(sim1[,2],sim1[,1],ylim = c(-3,4), col = "darkgrey")
lines(sim1[,2],sim1[,1], pch=2, col = "darkgrey")
points(sim2[,2],sim2[,1], pch=2, col = "darkgrey")
lines(sim2[,2],sim2[,1], pch=2, col = "darkgrey")
points(sim3[,2],sim3[,1], pch=2, col = "darkgrey")
lines(sim3[,2],sim3[,1], pch=2, col = "darkgrey")
lines(fit, , col = "red")
Which would give me this kind of figure:
Plot
But trying to plot it in a polar plot. I cannot get further than plotting each individually:
# Plot
library(plotrix)
polar.plot(sim1[,1],sim1[,2],lwd=3,line.col="red", radial.lim=c(-3,3),clockwise=TRUE,rp.type = "s")
polar.plot(sim2[,1],sim2[,2],lwd=3,line.col="blue", radial.lim=c(-3,3),clockwise=TRUE,rp.type = "s")
polar.plot(sim3[,1],sim3[,2],lwd=3,line.col="darkgrey", radial.lim=c(-3,3),clockwise=TRUE,rp.type = "s")
Poor plot but 360
I have also tried using ggplot2 as well as plotly but nothing yielded what I was hoping for.

Use the add parameter to add lines. Perhaps something like this?
polar.plot(sim1[,1], sim1[,2], lwd=1, line.col = "grey20", radial.lim = c(-3,3),
clockwise = TRUE, rp.type = "p")
polar.plot(sim2[,1], sim2[,2], lwd=1, line.col = "grey20", radial.lim = c(-3,3),
clockwise = TRUE, rp.type = "p", add = TRUE)
polar.plot(sim3[,1], sim3[,2], lwd=1, line.col = "grey20", radial.lim = c(-3,3),
clockwise = TRUE, rp.type = "p", add = TRUE)
polar.plot(fit$y, fit$x, lwd=2, line.col = "firebrick", radial.lim = c(-3,3),
clockwise = TRUE, rp.type = "p", add = TRUE)

GGplot alternative:
library(ggplot2,ggthemes)
# Data for test
set.seed(35)
sim1 <- cbind(rnorm(6,0),seq(0,359,359/5))
sim2 <- cbind(rnorm(9,0),seq(0,359,359/8))
sim3 <- cbind(rnorm(7,0),seq(0,359,359/6))
# Create spline for points
total <- rbind(sim1,sim2,sim3)
colnames(total)=c('Col1','Col2')
total=as.data.frame(total)
MyNames=c(rep('sim1',nrow(sim1)),rep('sim2',nrow(sim2)),rep('sim3',nrow(sim3)))
total=cbind(MyNames,total)
Radial=ggplot(total)+
theme_light()+
geom_line(aes(x=Col2,y=Col1,group=MyNames,colour=MyNames),alpha=0.4)+
geom_point(aes(x=Col2,y=Col1,group=MyNames,colour=MyNames))+
geom_line(aes(x=Col2,y=Col1),stat='smooth', method = "loess", span=0.5, alpha=0.4, size=1.2)+
scale_x_continuous(breaks=seq(0,360,by=60),expand=c(0,0),lim=c(0,360))+
coord_polar(theta='x',start=0)+
ggtitle('Sim')+
theme(axis.text=element_text(size=14),axis.title=element_text(size=16,face="bold"),legend.text=element_text(size=14),legend.title=element_text(size=14),title=element_text(size=16,face="bold"),plot.title = element_text(hjust = 0.5))
Radial

Related

RDA triplot in R- plot only numeric explanatory variables as arrows; factors as centroids

I ran a distance-based RDA using capscale() in the vegan library in R and I am trying to plot my results as a custom triplot. I only want numeric or continuous explanatory variables to be plotted as arrows/vectors. Currently, both factors and numeric explanatory variables are being plotted with arrows, and I want to remove arrows for factors (site and year) and plot centroids for these instead.
dbRDA=capscale(species ~ canopy+gmpatch+site+year+Condition(pair), data=env, dist="bray")
To plot I extracted % explained by the first 2 axes as well as scores (coordinates in RDA space)
perc <- round(100*(summary(spe.rda.signif)$cont$importance[2, 1:2]), 2)
sc_si <- scores(spe.rda.signif, display="sites", choices=c(1,2), scaling=1)
sc_sp <- scores(spe.rda.signif, display="species", choices=c(1,2), scaling=1)
sc_bp <- scores(spe.rda.signif, display="bp", choices=c(1, 2), scaling=1)
I then set up a blank plot with scaling, axes, and labels
dbRDAplot<-plot(spe.rda.signif,
scaling = 1, # set scaling type
type = "none", # this excludes the plotting of any points from the results
frame = FALSE,
# set axis limits
xlim = c(-1,1),
ylim = c(-1,1),
# label the plot (title, and axes)
main = "Triplot db-RDA - scaling 1",
xlab = paste0("db-RDA1 (", perc[1], "%)"),
ylab = paste0("db-RDA2 (", perc[2], "%)"))
Created a legend and added points for site scores and text for species
pchh <- c(2, 17, 1, 19)
ccols <- c("black", "red", "black", "red")
legend("topleft", c("2016 MC", "2016 SP", "2018 MC", "2018 SP"), pch = pchh[unique(as.numeric(as.factor(env$siteyr)))], pt.bg = ccols[unique(as.factor(env$siteyr))], bty = "n")
points(sc_si,
pch = pchh[as.numeric(as.factor(env$siteyr))], # set shape
col = ccols[as.factor(env$siteyr)], # outline colour
bg = ccols[as.factor(env$siteyr)], # fill colour
cex = 1.2) # size
text(sc_sp , # text(sc_sp + c(0.02, 0.08) tp adjust text coordinates to avoid overlap with points
labels = rownames(sc_sp),
col = "black",
font = 1, # bold
cex = 0.7)
Here is where I add arrows for explanatory variables, but I want to be selective and do so for numeric variables only (canopy and gmpatch). The variables site and year I want to plot as centroids, but unsure how to do this. Note that the data structure for these are definitely specified as factors already.
arrows(0,0, # start them from (0,0)
sc_bp[,1], sc_bp[,2], # end them at the score value
col = "red",
lwd = 2)
text(x = sc_bp[,1] -0.1, # adjust text coordinate to avoid overlap with arrow tip
y = sc_bp[,2] - 0.03,
labels = rownames(sc_bp),
col = "red",
cex = 1,
font = 1)
#JariOksanen thank you for your answer. I was able to use the following to fix the problem
text(dbRDA, choices = c(1, 2),"cn", arrow=FALSE, length=0.05, col="red", cex=0.8, xpd=TRUE)
text(dbRDA, display = "bp", labels = c("canopy", "gmpatch"), choices = c(1, 2),scaling = "species", arrow=TRUE, select = c("canopy", "gmpatch"), col="red", cex=0.8, xpd = TRUE)
#JariOksanen thank you for your answer. I was able to use the following to fix the problem
text(dbRDA, choices = c(1, 2),"cn", arrow=FALSE, length=0.05, col="red", cex=0.8, xpd=TRUE)
text(dbRDA, display = "bp", labels = c("canopy", "gmpatch"), choices = c(1, 2),scaling = "species", arrow=TRUE, select = c("canopy", "gmpatch"), col="red", cex=0.8, xpd = TRUE)

How can I change the colour of my points on my db-RDA triplot in R?

QUESTION: I am building a triplot for the results of my distance-based RDA in R, library(vegan). I can get a triplot to build, but can't figure out how to make the colours of my sites different based on their location. Code below.
#running the db-RDA
spe.rda.signif=capscale(species~canopy+gmpatch+site+year+Condition(pair), data=env, dist="bray")
#extract % explained by first 2 axes
perc <- round(100*(summary(spe.rda.signif)$cont$importance[2, 1:2]), 2)
#extract scores (coordinates in RDA space)
sc_si <- scores(spe.rda.signif, display="sites", choices=c(1,2), scaling=1)
sc_sp <- scores(spe.rda.signif, display="species", choices=c(1,2), scaling=1)
sc_bp <- scores(spe.rda.signif, display="bp", choices=c(1, 2), scaling=1)
#These are my location or site names that I want to use to define the colours of my points
site_names <-env$site
site_names
#set up blank plot with scaling, axes, and labels
plot(spe.rda.signif,
scaling = 1,
type = "none",
frame = FALSE,
xlim = c(-1,1),
ylim = c(-1,1),
main = "Triplot db-RDA - scaling 1",
xlab = paste0("db-RDA1 (", perc[1], "%)"),
ylab = paste0("db-RDA2 (", perc[2], "%)")
)
#add points for site scores - these are the ones that I want to be two different colours based on the labels in the original data, i.e., env$site or site_names defined above. I have copied the current state of the graph
points(sc_si,
pch = 21, # set shape (here, circle with a fill colour)
col = "black", # outline colour
bg = "steelblue", # fill colour
cex = 1.2) # size
Current graph
I am able to add species names and arrows for environmental predictors, but am just stuck on how to change the colour of the site points to reflect their location (I have two locations defined in my original data). I can get them labelled with text, but that is messy.
Any help appreciated!
I have tried separating shape or colour of point by site_name, but no luck.
If you only have a few groups (in your case, two), you could make the group a factor (within the plot call). In R, factors are represented as an integer "behind the scenes" - you can represent up to 8 colors in base R using a simple integer:
set.seed(123)
df <- data.frame(xvals = runif(100),
yvals = runif(100),
group = sample(c("A", "B"), 100, replace = TRUE))
plot(df[1:2], pch = 21, bg = as.factor(df$group),
bty = "n", xlim = c(-1, 2), ylim = c(-1, 2))
legend("topright", unique(df$group), pch = 21,
pt.bg = unique(as.factor(df$group)), bty = "n")
If you have more than 8 groups, or if you would like to define your own colors, you can simply create a vector of colors the length of your groups and still use the same factor method, though with a few slight tweaks:
# data with 10 groups
set.seed(123)
df <- data.frame(xvals = runif(100),
yvals = runif(100),
group = sample(LETTERS[1:10], 100, replace = TRUE))
# 10 group colors
ccols <- c("red", "orange", "blue", "steelblue", "maroon",
"purple", "green", "lightgreen", "salmon", "yellow")
plot(df[1:2], pch = 21, bg = ccols[as.factor(df$group)],
bty = "n", xlim = c(-1, 2), ylim = c(-1, 2))
legend("topright", unique(df$group), pch = 21,
pt.bg = ccols[unique(as.factor(df$group))], bty = "n")
For pch just a slight tweak to wrap it in as.numeric:
pchh <- c(21, 22)
ccols <- c("slateblue", "maroon")
plot(df[1:2], pch = pchh[as.numeric(as.factor(df$group))], bg = ccols[as.factor(df$group)],
bty = "n", xlim = c(-1, 2), ylim = c(-1, 2))
legend("topright", unique(df$group),
pch = pchh[unique(as.numeric(as.factor(df$group)))],
pt.bg = ccols[unique(as.factor(df$group))], bty = "n")

Add calculated mean value to vertical line in plot in R

I have created a density plot with a vertical line reflecting the mean - I would like to include the calculated mean number in the graph but don't know how
(for example the mean 1.2 should appear in the graph).
beta_budget[,2] is the column which includes the different numbers of the price.
windows()
plot(density(beta_budget[,2]), xlim= c(-0.1,15), type ="l", xlab = "Beta Coefficients", main = "Preis", col = "black")
abline(v=mean(beta_budget[,2]), col="blue")
legend("topright", legend = c("Price", "Mean"), col = c("black", "blue"), lty=1, cex=0.8)
I tried it with the text command but it didn't work...
Thank you for your advise!
Something along these lines:
Data:
set.seed(123)
df <- data.frame(
v1 = rnorm(1000)
)
Draw histogram with density line:
hist(df$v1, freq = F, main = "")
lines(density(df$v1, kernel = "cosine", bw = 0.5))
abline(v = mean(df$v1), col = "blue", lty = 3, lwd = 2)
Include the mean as a text element:
text(mean(df$v1), # position of text on x-axis
max(density(df$v1)[[2]]), # position of text on y-axis
mean(df$v1), # text to be plotted
pos = 4, srt = 270, cex = 0.8, col = "blue") # some graphical parameters

Plot multipoints and a best fit line

I want to create one plot graph with the Roundrobin and Prediction points, without colors, where the Roundrobin and Prediction type of points are different, and it has a legend. I was want to add a best fit line for the results.
I am having trouble in adding all these features into one graph that has 2 points. I am used to Gnuplot, but I don't know how to do this with R. How I do this with R?
[1] Input data
Inputdata,Roundrobin,Prediction
1,178,188
2,159,185
3,140,175
[2] Script to generate data
no_faults_data <- read.csv("testresults.csv", header=TRUE, sep=",")
# Graph 1
plot(no_faults_data$Inputdata, no_faults_data$Roundrobin,ylim = range(c(no_faults_data$Roundrobin,no_faults_data$Prediction)),xlab="Input data size (MB)", ylab="Makespan (seconds)")
points(no_faults_data$Inputdata, no_faults_data$Prediction)
abline(no_faults_data$Inputdata, no_faults_data$Roundrobin, untf = FALSE, \dots)
abline(no_faults_data$Inputdata, no_faults_data$Prediction, untf = FALSE, \dots)
legend("top", notitle, c("Round-robin","Prediction"), fill=terrain.colors(2), horiz=TRUE)
In base R you will have to create a fitted model first:
robin <- lm(Roundrobin ~ Inputdata, data = no_faults_data)
pred <- lm(Prediction ~ Inputdata, data = no_faults_data)
plot(no_faults_data$Inputdata, no_faults_data$Roundrobin,
ylim = range(c(no_faults_data$Roundrobin,no_faults_data$Prediction)),
xlab = "Input data size (MB)", ylab = "Makespan (seconds)",
col = "green", pch = 19, cex = 1.5)
points(no_faults_data$Inputdata, no_faults_data$Prediction, pch = 22, cex = 1.5)
abline(robin, lty = 1)
abline(pred, lty = 5)
legend(1.1, 155, legend = c("Round-robin","Prediction"), pch = c(19,22), col = c("green","black"),
bty = "n", cex = 1.2)
which gives:
For further customization of the base R plot, see ?par and ?legend.
With ggplot2 you will need to reshape your data into long format:
library(reshape2)
library(ggplot2)
ggplot(melt(no_faults_data, id="Inputdata"),
aes(x=Inputdata, y=value, shape=variable, color=variable)) +
geom_point(size=4) +
geom_smooth(method = "lm", se = FALSE) +
theme_minimal()
which gives:
Used data:
no_faults_data <- read.csv(text="Inputdata,Roundrobin,Prediction
1,178,188
2,159,185
3,140,175", header=TRUE)
You should look into the ggplot2 package for plotting. Maybe not needed for the 3 points data you provided but it makes much nicer plots than the default.
df <- data.frame("Inputdata" = c(1,2,3,1,2,3), "score" = c(178,159,140,188,185,175), "scoreType" = c(rep("Roundrobin",3), rep("Prediction",3)))
p <- ggplot(data=df, aes(x=Inputdata, y=score, group=scoreType, shape = scoreType)) + geom_point(size=5)
p <- p + ggtitle("My Title")
p+stat_smooth(method="lm",se = FALSE)
Here you group by the type of score and let GG plot make the legend for you. stat_smooth is using lm here.

Adding point and lines to 3D scatter plot in R

I want to visualize concentration ellipsoids in 3d scatter plot in respect of principal components (principal components as axes of these ellipsoids). I used function scatter3d with option ellipsoid = TRUE
data3d <- iris[which(iris$Species == "versicolor"), ]
library(car)
library(rgl)
scatter3d(x = data3d[,1], y = data3d[,2], z = data3d[,3],
surface=FALSE, grid = TRUE, ellipsoid = TRUE,
axis.col = c("black", "black", "black"), axis.scales = FALSE,
xlab = "X1", ylab = "X2", zlab = "X3", surface.col = "blue",
revolution=0, ellipsoid.alpha = 0.0, level=0.7, point.col = "yellow", add=TRUE)
to draw this plot:
Then I was trying to add "mean point" using
points3d(mean(data3d[,1]), mean(data3d[,2]), mean(data3d[,3]), col="red", size=20)
but this point is not in the place it's supposed to be (in the center of ellipsoid):
and I'm wondering why and how can I rescale it (?). And another question, which will arise after this how can I add axes of this ellipsoid to the plot?
Looking at car:::scatter3d.default shows that the coordinates are internally scaled by the min and max of each dimension; the following code scales before plotting:
sc <- function(x,orig) {
d <- diff(range(orig))
m <- min(orig)
(x-m)/d
}
msc <- function(x) {
sc(mean(x),x)
}
points3d(msc(data3d[,1]),
msc(data3d[,2]),
msc(data3d[,3]), col="red", size=20)

Resources