Vectorize the legend in R - r

I have a question, I have several variables (apriori I don't know how many). And I want to plot them and add a legend for all of them automatically. I did this, but the problem is that I can't understand how to add expression here. I want that the legend looks like $b_1$ and not beta[1].
I have a matrix: beta_tilde. And I plot it:
n <- 5
beta_tilde <- matrix(rnorm(100*n), nr = 100)
ts.plot(beta_tilde, ylim = c(min(beta_tilde), max(beta_tilde)), col = 1:n)
legend("topright" , legend = eval(substitute(paste("beta[", v,"]", sep = ""), list(v=1:n))), col=1:n, lty=1, cex=0.7)

substitute doesn't return an expression vector of length greater 1. Your approach with eval and paste is misguided anyway. You should study some examples of computing on the language.
I find a for loop easiest here:
leg <- vector("expression", n)
for (i in seq_len(n)) leg[[i]] <- substitute(beta[v], list(v = i))
legend("topright", legend = leg, col=1:n, lty=1, cex=0.7)

Related

plot all rows of matrix in the same plot in R

I want to create a plot.
x values are matt 's colnames : count.4, count.5, ...
y values are range of matt elements
the scatter POINTS on plot are corresponding matt[i,j] elemnts, such that points for each row have the same color.
for (rr in 2:8) {
rownames(matt)[rr-1] <- paste('class', rr, sep='.')
for(cc in 4:20) {
matt[rr-1, cc-3] <- rr * cc
colnames(matt)[cc-3] <- paste('count', cc, sep='.')
}
}
I am really stuck at how to get such plot. Any help or hint is very appreciated. I found
matplot (c(4:20), cbind(matt[1,]:mat[7,]), pch = 19, ylim = range(c(matt[1,]:mat[7,]))
I see cbind(matt[1,]:matt[7,]) is not of correct format. but I do not know how to write this such than for a matrix with many more rows I do not have to write all matt[j,]
how can I get to this?
Edit. this is the plot I get when I use cbind(matt[1,],matt[2,],...,matt[7,])
Other than the efficient way coding this, I do not know why there are two sets of black points. can I label colors to corresponding "class" so that the plot gets easier to be read.
Normally series are stored in columns, not in rows, but if they are in rows just use transpose. There are other color palettes available at ?rainbow and a long vector of colors available via colors() if you don't like the colors we used here. (We used the input in the Note at the end.)
col <- rainbow(length(rr))
matplot(cc, t(mat), pch = 19, col = col, type = "o")
legend("topleft", legend = rownames(mat), pch = 19, col = col, lty = 1)
Note
rr <- 2:8
cc <- 4:20
mat <- outer(rr, cc)
dimnames(mat) <- list(paste0("class.", rr), paste0("count.", cc))

How do I use different colors when plotting in a loop (R)

I am trying to plot 18 individual plots on a 3x6 multiplot in R. To be more efficient I have created these plots as a loop, however I would like the plots in each column to have their own color (i.e. the all the plots in column 1 would be red, all the plots in column 2 would be blue etc.). Is there a way I can do this while still retaining loop format?
par(mfcol = c(3,6))
for(i in 1:6)
{
plot(sigma_trace[,i], type ='l', main = paste("Sigma Traceplot Chain", i))
plot(theta_1_trace[,i], type = 'l', main = paste("Theta[1] Traceplot Chain", i))
plot(theta_2_trace[,i], type = 'l', main = paste("Theta[2] Traceplot Chain", i))
}
So basically, I think I want each loop statement to follow the same pattern of colours. Is this possible?
Thanks.
You can make a colour palette using RColorBrewer and then call each colour in your loop. For example.
library(RColorBrewer)
# set the colour palette
cols <- brewer.pal(4,'Set2')
# variables to plot
x = (1:250)/10
y = cos(x)
# plot in the loop
op <- par(mfrow = c(2, 2))
for (i in 1:4){
plot(x, y, col=cols[i], type='l', lwd=3)
}
par(op)
Here's an overview of the package.
In Base R you can use colorRampPalette() to create gradient, or you can even just make an object with the colours that you wan to reference:
plotcolors <- colorRampPalette(c("gold","blue"))(6)
par(mfrow = c(2, 3))
for(i in 1:6){
plot(1:10,1:10,type='l',col=plotcolors[i])
}
If you want to specify all 6 of your colours its as easy as modifying the above code
plotcolors <- c("red","blue","green","black","yellow","purple")

How to create a monomial plot in R?

I want to create a function, that result will be a plot of moniomals ( degree less than "n").
I wrote the simple code.
Monomial=function(m){
x=1:100
y=1:100
for(i in m) x2=x^m
plot(y,x2,type="l",col="red",xlab="Arguments",ylab="Values",
main=expression("Monomials"))
But for example: Monomial(3) I getting plot x^3. I need yet x^1 and x^2. How to name each line?
Here is what you need:
Monomial <- function(m){
x <- 1:100
cols <- palette(rainbow(m))
plot(x,x,type="l",col = cols[1],xlab="Arguments",ylab="Values",
main=expression("Monomials"))
for (d in 2:m){
lines(x, x^d, type="l", col=cols[d])
}
legend(90, 60, legend=c(as.character(paste0("x",1:m))),
col=cols, lty=1, cex=0.6)
}
You need to generate colors. This is what the cols variable achieves. lines adds a new curve to existing axes. Finally, ledend adds a legend to the plot.

R: Plot lines are very thick

When using matplot to plot a matrix using:
matplot(t, X[,1:4], col=1:4, lty = 1, xlab="Time", ylab="Stock Value")
my graph comes out as:
How do I reduce the line thickness? I previously used a different method and my graph was fine:
I have tried manupilating lwd but to no avail.
Even tried plot(t, X[1:4097,1]), yet the line being printed is very thick. Something wrong with my R?
EDIT: Here is the code I used to produce the matrix X:
####Inputs mean return, volatility, time period and time step
mu=0.25; sigma=2; T=1; n=2^(12); X0=5;
#############Generating trajectories for stocks
##NOTE: Seed is fixed. Changing seed will produce
##different trajectories
dt=T/n
t=seq(0,T,by=dt)
set.seed(201)
X <- matrix(nrow = n+1, ncol = 4)
for(i in 1:4){
X[,i] <- c(X0,mu*dt+sigma*sqrt(dt)*rnorm(n,mean=0,sd=1))
X[,i] <- cumsum(X[,i])
}
colnames(X) <- paste0("Stock", seq_len(ncol(X)))
Just needed to add type = "l" to matplot(....). Plots fine now.
matplot(t, X[,1:4], col=1:4, type = "l", xlab="Time", ylab="Stock Value")

Colorfill boxplot in R-cran with lines, dots, or similar

I need to use black and white color for my boxplots in R. I would like to colorfill the boxplot with lines and dots. For an example:
I imagine ggplot2 could do that but I can't find any way to do it.
Thank you in advance for your help!
I thought this was a great question and pondered if it was possible to do this in base R and to obtain the checkered look. So I put together some code that relies on boxplot.stats and polygon (which can draw angled lines). Here's the solution, which is really not ready for primetime, but is a solution that could be tinkered with to make more general.
boxpattern <-
function(y, xcenter, boxwidth, angle=NULL, angle.density=10, ...) {
# draw an individual box
bstats <- boxplot.stats(y)
bxmin <- bstats$stats[1]
bxq2 <- bstats$stats[2]
bxmedian <- bstats$stats[3]
bxq4 <- bstats$stats[4]
bxmax <- bstats$stats[5]
bleft <- xcenter-(boxwidth/2)
bright <- xcenter+(boxwidth/2)
# boxplot
polygon(c(bleft,bright,bright,bleft,bleft),
c(bxq2,bxq2,bxq4,bxq4,bxq2), angle=angle[1], density=angle.density)
polygon(c(bleft,bright,bright,bleft,bleft),
c(bxq2,bxq2,bxq4,bxq4,bxq2), angle=angle[2], density=angle.density)
# lines
segments(bleft,bxmedian,bright,bxmedian,lwd=3) # median
segments(bleft,bxmin,bright,bxmin,lwd=1) # min
segments(xcenter,bxmin,xcenter,bxq2,lwd=1)
segments(bleft,bxmax,bright,bxmax,lwd=1) # max
segments(xcenter,bxq4,xcenter,bxmax,lwd=1)
# outliers
if(length(bstats$out)>0){
for(i in 1:length(bstats$out))
points(xcenter,bstats$out[i])
}
}
drawboxplots <- function(y, x, boxwidth=1, angle=NULL, ...){
# figure out all the boxes and start the plot
groups <- split(y,as.factor(x))
len <- length(groups)
bxylim <- c((min(y)-0.04*abs(min(y))),(max(y)+0.04*max(y)))
xcenters <- seq(1,max(2,(len*(1.4))),length.out=len)
if(is.null(angle)){
angle <- seq(-90,75,length.out=len)
angle <- lapply(angle,function(x) c(x,x))
}
else if(!length(angle)==len)
stop("angle must be a vector or list of two-element vectors")
else if(!is.list(angle))
angle <- lapply(angle,function(x) c(x,x))
# draw plot area
plot(0, xlim=c(.97*(min(xcenters)-1), 1.04*(max(xcenters)+1)),
ylim=bxylim,
xlab="", xaxt="n",
ylab=names(y),
col="white", las=1)
axis(1, at=xcenters, labels=names(groups))
# draw boxplots
plots <- mapply(boxpattern, y=groups, xcenter=xcenters,
boxwidth=boxwidth, angle=angle, ...)
}
Some examples in action:
mydat <- data.frame(y=c(rnorm(200,1,4),rnorm(200,2,2)),
x=sort(rep(1:2,200)))
drawboxplots(mydat$y, mydat$x)
mydat <- data.frame(y=c(rnorm(200,1,4),rnorm(200,2,2),
rnorm(200,3,3),rnorm(400,-2,8)),
x=sort(rep(1:5,200)))
drawboxplots(mydat$y, mydat$x)
drawboxplots(mydat$y, mydat$x, boxwidth=.5, angle.density=30)
drawboxplots(mydat$y, mydat$x, # specify list of two-element angle parameters
angle=list(c(0,0),c(90,90),c(45,45),c(45,-45),c(0,90)))
EDIT: I wanted to add that one could also obtain dots as a fill by basically drawing a pattern of dots, then covering them a "donut"-shaped polygon, like so:
x <- rep(1:10,10)
y <- sort(x)
plot(y~x, xlim=c(0,11), ylim=c(0,11), pch=20)
outerbox.x <- c(2.5,0.5,10.5,10.5,0.5,0.5,2.5,7.5,7.5,2.5)
outerbox.y <- c(2.5,0.5,0.5,10.5,10.5,0.5,2.5,2.5,7.5,7.5)
polygon(outerbox.x,outerbox.y, col="white", border="white") # donut
polygon(c(2.5,2.5,7.5,7.5,2.5),c(2.5,2.5,2.5,7.5,7.5)) # inner box
But mixing that with angled lines in a single plotting function would be a bit difficult, and is generally a bit more challenging, but it starts to get you there.
I think it is hard to do this with ggplot2 since it dont use shading polygon(gris limitatipn). But you can use shading line feature in base plot, paramtered by density and angle arguments in some plot functions ( ploygon, barplot,..).
The problem that boxplot don't use this feature. So I hack it , or rather I hack bxp internally used by boxplot. The hack consist in adding 2 arguments (angle and density) to bxp function and add them internally in the call of xypolygon function ( This occurs in 2 lines).
my.bxp <- function (all.bxp.argument,angle,density, ...) {
.....#### bxp code
xypolygon(xx, yy, lty = boxlty[i], lwd = boxlwd[i],
border = boxcol[i],angle[i],density[i])
.......## bxp code after
xypolygon(xx, yy, lty = "blank", col = boxfill[i],angle[i],density[i])
......
}
Here an example. It should be noted that it is entirely the responsibility of the user to ensure
that the legend corresponds to the plot. So I add some code to rearrange the legend an the boxplot code.
require(stats)
set.seed(753)
(bx.p <- boxplot(split(rt(100, 4), gl(5, 20))))
layout(matrix(c(1,2),nrow=1),
width=c(4,1))
angles=c(60,30,40,50,60)
densities=c(50,30,40,50,30)
par(mar=c(5,4,4,0)) #Get rid of the margin on the right side
my.bxp(bx.p,angle=angles,density=densities)
par(mar=c(5,0,4,2)) #No margin on the left side
plot(c(0,1),type="n", axes=F, xlab="", ylab="")
legend("top", paste("region", 1:5),
angle=angles,density=densities)

Resources