I am trying to create a function to draw scatterplots of variables, something like the following:
plotting = function(x,y){
plot(x, y,
main= "PM10 and Electricity use",
ylab= "",
xlab= "",
col= "blue", pch = 19, cex = 1, lty = "solid", lwd = 2)
}
y = PM10
x = Total_E*population
plotting(x,y)
(Note: PM10, Total_E, population are all vectors of numbers.)
Is that possible to change xlab, ylab to the names of the variables, say ylab to "PM10", and xlab to "Total_E*population" or even "Total_E times population"?
you are looking for non-standard evaluation. This is accomplished with substitute and deparse. ...
plotting <- function(x, y) {
plot(x, y, main = "PM10 and Electricity use",
ylab = deparse(substitute(y)),
xlab = deparse(substitute(x))
)
}
Related
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)
I carried out a post-hoc Tukey test on an ANOVA and then I made a plot of the results. I can't seem to change my x axis title or my y axis title. I get this error:
Error in plot.default(c(xi[, "lwr"], xi[, "upr"]), rep.int(yvals, 2L), :
formal argument "xlab" matched by multiple actual arguments
This is my relevant code:
tuk <- TukeyHSD(final)
plot(tuk,xlab="Differences in mean departure times", ylab="Comparisons")
I also need to change the y axis tick mark labels but I don't know how.
Thanks.
So because of how they wrote the plot() method for TukeyHSD class object you can not change the axis labels by default, this detail is buried in the ?TuketHSD man page.
But you can easily hack together a copy that does allow you to do it. First find the code for the existing method with getAnywhere(plot.TukeyHSD). Then adapt it like so:
tuk_plot <- function (x, xlab, ylab, ylabels = NULL, ...) {
for (i in seq_along(x)) {
xi <- x[[i]][, -4L, drop = FALSE]
yvals <- nrow(xi):1L
dev.hold()
on.exit(dev.flush())
plot(c(xi[, "lwr"], xi[, "upr"]), rep.int(yvals, 2L),
type = "n", axes = FALSE, xlab = "", ylab = "", main = NULL,
...)
axis(1, ...)
# change for custom axis labels
if (is.null(ylabels)) ylabels <- dimnames(xi)[[1L]]
axis(2, at = nrow(xi):1, labels = ylabels,
srt = 0, ...)
abline(h = yvals, lty = 1, lwd = 0.5, col = "lightgray")
abline(v = 0, lty = 2, lwd = 0.5, ...)
segments(xi[, "lwr"], yvals, xi[, "upr"], yvals, ...)
segments(as.vector(xi), rep.int(yvals - 0.1, 3L), as.vector(xi),
rep.int(yvals + 0.1, 3L), ...)
title(main = paste0(format(100 * attr(x, "conf.level"),
digits = 2L), "% family-wise confidence level\n"),
# change for custom axis titles
xlab = xlab, ylab = ylab)
box()
dev.flush()
on.exit()
}
}
Now you can adjust the x and y axis along with custom y-labels:
tuk_plot(tuk, "Hello X Axis", "Hello Y Axis", c("One", "Two", "Three"))
If you don't provide the y-labels the default ones from the model will show up.
Reproducible Example:
fm1 <- aov(breaks ~ wool + tension, data = warpbreaks))
tuk <- TukeyHSD(fm1, "tension")
I have a 3D scatter plot that looks like this
and the code associated with it is as follows
nr = c(114,114,1820,100,100)
acc = c(70.00,45.00,98.89,82.00,74.90)
ti = c(25.00,87.50,0.25,41.40,51.30)
label = c(1, 2, 3, 4, 5)
data = data.frame(nr, acc, ti, label)
library(scatterplot3d)
scatterplot3d(data$nr, data$acc, data$ti, main = "3D Plot - Requirements, Accuracy & Time", xlab = "Number of requirements", ylab = "Accuracy", zlab = "Time", pch = data$label, angle = 45)
Now, I want to add a legend to the bottom right to indicate what those symbols mean
tech <- c('BPL','W','RT','S','WSM')
For instance, the triangle stands for BPL, + for RT and so on
You can try this:
library(scatterplot3d)
# define a plot
s3d <-scatterplot3d(data$nr, data$acc, data$ti, main = "3D Plot - Requirements, Accuracy & Time",
xlab = "Number of requirements", ylab = "Accuracy", zlab = "Time", pch = data$label, angle = 45)
# add a legend
legend("topright",s3d$xyz.convert(18, 0, 12), pch = data$label, yjust=0,
# here you define the labels in the legend
legend = c('BPL','W','RT','S','WSM'), cex = 1.1
)
I'm currently trying to plot the components found via EM algorithm. However, the estimated densities do not extend fully to the end. It looks like this:
My code is:
plot(EM_data, which=2, xlim= c(0, 80), xlab2= "", yaxt= "n", main2 ="", lwd2=0.8, border = "azure3")
lines(density(EM_data), lty=2, lwd=0.8)
The plot is truncated wether I specify xlim or not. xlim2 is not defined for this type of plot. Where am I going wrong?
The method to plot mixEM only draws within the range of the data, if you want to extend the densities you must build your own function.
Use something like this:
Example data:
library(mixtools)
data(faithful)
attach(faithful)
set.seed(100)
EM_data<-normalmixEM(waiting, arbvar = FALSE, epsilon = 1e-03)
mixtools plot:
plot(EM_data, which=2, xlim= c(30, 110), xlab2= "", yaxt= "n", main2 ="",
lwd2=0.8, border = "azure3")
lines(density(EM_data$x), lty=2, lwd=0.8)
Adaptation by extending densities:
a <- hist(EM_data$x, plot = FALSE)
maxy <- max(max(a$density), 0.3989 * EM_data$lambda/EM_data$sigma)
hist(EM_data$x, prob = TRUE, main = "", xlab = "", xlim= c(30, 110),
ylim = c(0, maxy), yaxt= "n", border = "azure3")
for (i in 1:ncol(EM_data$posterior)) {
curve(EM_data$lambda[i] * dnorm(x, mean = EM_data$mu[i], sd = EM_data$sigma[i]),
col = 1 + i, lwd = 0.8, add = TRUE)
}
lines(density(EM_data$x), lty=2, lwd=0.8)
I want to plot my points on a graph and then show the density distribution on the x-axis and on the y-axis at the same time.
I'm able to do it on the x axis but not on the y axis.
par(mfrow=c(1,1))
plot(rnorm(100))
par(new=TRUE)
plot(density(rnorm(100,10,123)), ann = FALSE, xlab = "", ylab ="",xaxt='n', yaxt='n')
par(new=TRUE)
plot(density(rnorm(100, 10,12)), col = "red", ann = FALSE, xlab = "", ylab ="",xaxt='n', yaxt='n')
There is no reason you can't.
set.seed(0)
d1 <- density(rnorm(100, 10, 123))
d2 <- density(rnorm(100, 10, 130))
## shared x, y, range / limit
xlim <- c(min(d1$x[1], d2$x[1]), max(d1$x[512], d2$x[512])) ## default: n = 512
ylim <- c(0, max(d1$y, d2$y))
## conventional plot
plot(d1$x, d1$y, type = "l", xlim = xlim, ylim = ylim)
lines(d2$x, d2$y, col = 2)
## rotated plot
plot(d1$y, d1$x, type = "l", xlim = ylim, ylim = xlim)
lines(d2$y, d2$x, col = 2)
Remarks:
never use par(new = TRUE); set xlim and ylim yourself;
customize the plot with title, axis display yourself.