Is is possible to add a title to scatter.smooth? - r

I use often scatter.smooth function but I wonder if it is possible to add a title or main argument directly to this function. I read the description of the function but have not found the possibility. I know that there are other ways to do this but I want to keep this one if possible.
d <- data.frame(x = sample(20, 500, prob=c(1:10, 10:1), replace = TRUE),
y = sample(20, 500, prob=c(1:10, 10:1), replace = TRUE),
z = rnorm(500, 20, 4))
mo <- lm(y ~ z, d)
fig <- function(x) {
scatter.smooth(fitted(x), residuals(x, type = "response"), col = "red")
abline(0, 0, lty = 2)
legend("topright", legend = c("loss", "0-0"), lty = c(1, 2))
}
fig(mo)

You look at the help page of scatter.smooth, you see that the ... argument is passed on to plot. Therefore, you can us any argument that plot accepts. Also main=.
You can also add a title to any graph using mtext which adds text to the figure margins.
So, you can do:
fig(mo)
mtext("My title", side=3, line=1)
Or modify your fig function:
fig <- function(x, ...) {
scatter.smooth(fitted(x), residuals(x, type = "response"),
col = "red", ...)
abline(0, 0, lty = 2)
legend("topright", legend = c("loss", "0-0"), lty = c(1, 2))
}
fig(mo, main="My title")

Just add main to the smooth function:
scatter.smooth(x, y, ylab = "Yname", xlab = "Xname", main = "Title")
It works

Related

How do I plot a legend next to my title (outside plot) using R?

I'm using base R plot(), and I want a legend (a color block and key) to show up above (outside) the top right of my plot next to my title (generated using title()).
What's the best way to do this?
Maybe something like this is what you're looking for:
x <- c(1,2,3,4)
y <- c(4,1,3,2)
z <- c(1,2,3,4)
dat <- data.frame(x,y,z)
windows(width = 5, height = 9) #quartz() on Mac
layout(matrix(c(1,2), 2, 1, byrow = TRUE), heights=c(0.5,1))
par(oma = c(4,3,0,0) + 0.1, mar = c(0,0,1,1) + 0.1)
plot(dat$x, y=rep(1,4), type = "n", axes = F, ylab = "", xlab = "")
legend(x = "bottomright", legend = c("y", "z"), fill = c("blue", "red"))
plot(dat$x, dat$y, type = "n", main = "PLOT")
lines(z, col = "red")
lines(y, col = "blue")
Basically this makes two plots, one is just invisible and shortened so all that's displayed is the legend.
You may be able to addtionally tweak the margins around the legend and other graphical parameters (?par) to get the layout better.

R need to make this process faster--for loop, function, or something else

I have a set of code, below, and I need to run it 120 times, with the variables modified, of course, for each run. I tried a for loop and I tried to create a function. I just want to do this process faster. Can someone please help me? The variables I need to have modified are score and seconds. So, it would be score1, seconds1 for the first run, score2, seconds2 for the second run, and so on. Thank you.
pre <- aggregate(score~seconds, dataframe, FUN = sum)
freqsdf <- data.frame(table(SecsOnly$seconds))
condp <- pre$score/freqsdf$Freq
condp <- data.frame(condp)
par(mar = c(5,5,5,5))
hist(dataframe$seconds, xlab = "", ylab = "", ylim = c(0, 25), axes = FALSE, col = "grey", main = 'title here', breaks = 100)
axis(4, ylim = c(0, 25), col = "black", col.axis = "black", las = 2, cex.axis = 1)
par(new = TRUE)
plot(pres$seconds, condp$condp, col = "red" , type = "l", xlab = "Time", ylab = "y axis label", ylim=c(0,1.0))
abline(h = 0.20)

Put one line chart and bar chart in one plot in R (Not ggplot)?

how to
Combine a bar chart and line in single plot in R (from different data sources)?
Say I have two data sources as:
barData<-c(0.1,0.2,0.3,0.4) #In percentage
lineData<-c(100,22,534,52,900)
Note that they may not be in the same scale.
Can I plot both barData and LineData in one plot and make them good looking ?
I cant use ggplot in this case so this is not a duplicated question..
Something like the following:
Maybe this helps as a starting point:
par(mar = rep(4, 4))
barData<-c(0.1,0.2,0.3,0.4) * 100
y <- lineData<-c(100,22,534,900);
x <- barplot(barData,
axes = FALSE,
col = "blue",
xlab = "",
ylab = "",
ylim = c(0, 100) )[, 1]
axis(1, at = x, labels = c("Julia", "Pat", "Max", "Norman"))
ats <- c(seq(0, 100, 15), 100); axis(4, at = ats, labels = paste0(ats, "%"), las = 2)
axis(3, at = x, labels = NA)
par(new = TRUE)
plot(x = x, y = y, type = "b", col = "red", axes = FALSE, xlab = "", ylab = "")
axis(2, at = c(pretty(lineData), max(lineData)), las = 2)
mtext(text="Lines of code by Programmer", side = 3, line = 1)
box()

Overlapping stacked density plots

I'm trying to achieve a similar plot to this one, using R's native plot command.
I was able to get something similar with the code below, however, I'd like the density polygons to overlap. Can anyone suggest a way to do this?
data = lapply(1:5, function(x) density(rnorm(100, mean = x)))
par(mfrow=c(5,1))
for(i in 1:length(data)){
plot(data[[i]], xaxt='n', yaxt='n', main='', xlim=c(-2, 8), xlab='', ylab='', bty='n', lwd=1)
polygon(data[[i]], col=rgb(0,0,0,.4), border=NA)
abline(h=0, lwd=0.5)
}
Outputs:
I would do it something like the following. I plot the densities in the same plot but add an integer to the y values. To make them overlapping i multiply by a constant factor fac.
# Create your toy data
data <- lapply(1:5, function(x) density(rnorm(100, mean = x)))
fac <- 5 # A factor to make the densities overlap
# We make a empty plot
plot(1, type = "n", xlim = c(-3, 10), ylim = c(1, length(data) + 2),
axes = FALSE, xlab = "", ylab = "")
# Add each density, shifted by i and scaled by fac
for(i in 1:length(data)){
lines( data[[i]]$x, fac*data[[i]]$y + i)
polygon(data[[i]]$x, fac*data[[i]]$y + i, col = rgb(0, 0, 0, 0.4), border = NA)
abline(h = i, lwd = 0.5)
}
(Note: This content was previously edited into the Question and was written by #by0.)
Thanks to #AEBilgrau, I quickly put together this function which works really nicely. Note: you need to play around with the factor fac depending on your data.
stacked.density <- function(data, fac = 3, xlim, col = 'black',
alpha = 0.4, show.xaxis = T,
xlab = '', ylab = ''){
xvals = unlist(lapply(data, function(d) d$x))
if(missing(xlim)) xlim=c(min(xvals), max(xvals))
col = sapply(col, col2alpha, alpha)
if(length(col) == 1) col = rep(col, length(data))
plot(1, type = "n", xlim = xlim, ylim = c(1,length(data) + 2),
yaxt='n', bty='n', xaxt=ifelse(show.xaxis, 'l', 'n'), xlab = xlab, ylab = ylab)
z = length(data):1
for(i in 1:length(data)){
d = data[[ z[i] ]]
lines(d$x, fac*d$y + i, lwd=1)
polygon(d$x, fac*d$y+ i, col=col[i], border=NA)
abline(h = i, lwd=0.5)
}
}
data <- lapply(1:5, function(x) density(rnorm(100, mean = x)))
stacked.density(data, col=c('red', 'purple', 'blue', 'green', 'yellow'), alpha=0.3, show.xaxis=T)
outputs:

plot axis labels with multiple colours

I'm making plots like the one generated with the following code:
var1 <- sort(runif(10, 0, 1), decreasing = TRUE)
var2 <- sort(runif(10, 0, 1))
plot(var1, pch = 20, ylab = c("Var 1", "Var 2"))
points(var2, pch = 20, col = "grey")
Is there a way, with just the R graphics package, to place a black circle before Var 1 and a grey circle before Var 2 in the y axis label, to avoid having to insert a legend? Or alternatively, a way to use different text colours (black for Var 1 and grey for Var 2) in the y axis? I tried using col.lab = c("black","grey"), but it says Error in plot.window(...) : graphical parameter "col.lab" has the wrong length.
Many thanks in advance,
Márcia
I'm not sure how to add the point to the label, but an easy way to labe with color can be done in the following way:
var1 <- sort(runif(10, 0, 1), decreasing = TRUE)
var2 <- sort(runif(10, 0, 1))
plot(var1, pch = 20, ylab = "")
points(var2, pch = 20, col = "grey")
mtext("Var 1", side=2, line=2)
mtext("Var 2", side=2, line=3, col="grey")
Would something like this work for you? It's a bit busy on the left axis, but I think it shows what you are asking about.
> var1 <- sort(runif(10, 0, 1), decreasing = TRUE)
> var2 <- sort(runif(10, 0, 1))
> plot(var1, ylim = range(c(var1, var2)), pch = 20, ylab = "", axes = FALSE)
> points(var2, pch = 20, col = "grey")
> labs <- round(sort(c(var1, var2)), 1)
> axis(1)
> axis(2, at = sort(c(var1, var2)), labels = labs)
> sapply(var1, function(x) points(-0.1, x, pch = 20))
> sapply(var2, function(x) points(-0.1, x, pch = 20, col = "grey"))
> box()

Resources