How to change values on y-axis for lattice xyplot - r

I have an xy plot in lattice on which I'm showing four different things. The plot looks like this right now. The values for pink line range from 1 to 15000, however, values for other lines range from 20 to 300. This is why all lines other than pink seem static. However, there are fluctuations in them but I feel the graph isn't showing them property because of yaxis. Is there a way I can shorten the yaxis such that the graph is better representing the other lines as well?
This is how it looks when I don't plot the pink line all together. This shows there are fluctuations which I'd like to show.

If you can use the base package instead of lattice it is quite simple. The code below is vastly simplified from one of my own plots. You will have to fiddle a little with it to add two more lines.
line description
1,2 plot from a data frame. ylab will be on side 2 (left) scale will be automatically determined from the data
3 start a second plot
4 plot from a data frame, use axes=FALSE, xlab=NA, ylab=NA
5 create the axis for side 4 (right) scale will be automatically determined from the data
6 make the ylab for side 4
1 plot(df[c(4,5)], type = "s", col = "blue", main = "Battery Life",
2 xlab="minutes", ylab="percent")
3 par(new=TRUE)
4 plot(df[c(4,6)], type = "s", col = "red", axes = FALSE, xlab = NA, ylab = NA)
5 axis(side = 4)
6 mtext(side = 4, line = 3, "Slope ( minutes)")

You can use the latticeExtra package to create a graph with 2 separate y-axis.
As the comments suggest, I would rather create 2 separate plots. It's a cleaner solution.
As an alternativ: maybe you could add a conditioning variable to your data ("magnitude" or so) which groups your data into suitable chunks. Then you could present your data as shown below.
library("lattice")
library("latticeExtra")
dat1 <- data.frame(x=1:100, y1=rep(1:10,10), y2=rep(100:91,10))
dat2 <- data.frame(x=1:200, y=c(rep(1:10,10), rep(100:91,10)),
z=c(rep("small",100), rep("huge",100)))
p1 <- xyplot(y1~x, data=dat1, type="l")
p2 <- xyplot(y2~x, data=dat1, type="l")
doubleYScale(p1, p2) # 2 y-axis: bad
xyplot(y ~ x | z, data=dat2, type="l", scales="free") # 2 plots: good

Related

Squeezing the gap r basic plot with different levels of y axis

I want to squeeze (narrow the gap) between the yellow line and the rest of the graph in the basic r plot through having different levels of y-axis labels. How can I do that?
my code is as follows:
Site <- subset(data, Sites == "Bx")
plot(SiteB$value,xlim = c(1,18),ylim=c(4,99.5),xlab="",ylab="",lwd=2,type = "n", asp = NA)
lines(SiteB$value,SiteB$A,type="l", col="orange",lwd=2)
lines(SiteB$value,SiteB$D, type="l", col="purple",lwd=2)
lines(SiteB$value,SiteB$G,type="l", col="blue",lwd=2)
lines(SiteB$value,SiteB$L,type="l",col="red",lwd=2)
lines(SiteB$value,SiteB$M,type="l", col="black",lwd=2)
#lines(SiteB$value,SiteB$S, type="l", col="magenta",lwd=2)
lines(SiteB$value,SiteB$T,type="l",col="green",lwd=2)

How to add colour matched legend to a R matplot

I plot several lines on a graph using matplot:
matplot(cumsum(as.data.frame(daily.pnl)),type="l")
This gives me default colours for each line - which is fine,
But I now want to add a legend that reflects those same colours - how can I achieve that?
PLEASE NOTE - I am trying NOT to specify the colours to matplot in the first place.
legend(0,0,legend=spot.names,lty=1)
Gives me all the same colour.
The default color parameter to matplot is a sequence over the nbr of column of your data.frame. So you can add legend like this :
nn <- ncol(daily.pnl)
legend("top", colnames(daily.pnl),col=seq_len(nn),cex=0.8,fill=seq_len(nn))
Using cars data set as example, here the complete code to add a legend. Better to use layout to add the legend in a pretty manner.
daily.pnl <- cars
nn <- ncol(daily.pnl)
layout(matrix(c(1,2),nrow=1), width=c(4,1))
par(mar=c(5,4,4,0)) #No margin on the right side
matplot(cumsum(as.data.frame(daily.pnl)),type="l")
par(mar=c(5,0,4,2)) #No margin on the left side
plot(c(0,1),type="n", axes=F, xlab="", ylab="")
legend("center", colnames(daily.pnl),col=seq_len(nn),cex=0.8,fill=seq_len(nn))
I have tried to reproduce what you are looking for using the iris dataset. I get the plot with the following expression:
matplot(cumsum(iris[,1:4]), type = "l")
Then, to add a legend, you can specify the default lines colour and type, i.e., numbers 1:4 as follows:
legend(0, 800, legend = colnames(iris)[1:4], col = 1:4, lty = 1:4)
Now you have the same in the legend and in the plot. Note that you might need to change the coordinates for the legend accordingly.
I like the #agstudy's trick to have a nice legend.
For the sake of comparison, I took #agstudy's example and plotted it with ggplot2:
The first step is to "melt" the data-set
require(reshape2)
df <- data.frame(x=1:nrow(cars), cumsum(data.frame(cars)))
df.melted <- melt(df, id="x")
The second step looks rather simple in comparison to the solution with matplot
require(ggplot2)
qplot(x=x, y=value, color=variable, data=df.melted, geom="line")
Interestingly #agstudy solution does the trick, but only for n ≤ 6
Here we have a matrix with 8 columns. The colour of the first 6 labels are correct.
The 7th and 8th are wrong. The colour in the plots restarts from the beginning (black, red ...) , whereas in the label it continues (yellow, grey, ...)
Still haven't figured out why this is the case. I'll maybe update this post with my findings.
matplot(x = lambda, y = t(ridge$coef), type = "l", main="Ridge regression", xlab="λ", ylab="Coefficient-value", log = "x")
nr = nrow(ridge$coef)
legend("topright", rownames(ridge$coef), col=seq_len(nr), cex=0.8, lty=seq_len(nr), lwd=2)
Just discovered that matplot uses linetypes 1:5 and colors 1:6 to establish the appearance of the lines. If you want to create a legend try the following approach:
## Plot multiple columns of the data frame 'GW' with matplot
cstart = 10 # from column
cend = cstart + 20 # to column
nr <- cstart:cend
ltyp <- rep(1:5, times=length(nr)/5, each=1) # the line types matplot uses
cols <- rep(1:6, times=length(nr)/6, each=1) # the cols matplot uses
matplot(x,GW[,nr],type='l')
legend("bottomright", as.character(nr), col=cols, cex=0.8, lty=ltyp, ncol=3)

Labels/points colored by category with PCA

I'm using prcomp to do PCA analysis in R, I want to plot my PC1 vs PC2 with different color text labels for each of the two categories,
I do the plot with:
plot(pca$x, main = "PC1 Vs PC2", xlim=c(-120,+120), ylim = c(-70,50))
then to draw in all the text with the different colors I've tried:
text(pca$x[,1][1:18], pca$[,1][1:18], labels=rownames(cava), col="green",
adj=c(0.3,-0.5))
text(pca$x[,1][19:35], pca$[,1][19:35], labels=rownames(cava), col="red",
adj=c(0.3,-0.5))
But R seams to plot 2 numbers over each other instead of one, the pcs$x[,1][1:18] plots the correct points I know because if I use that plot the points it works and produces the same plot as plot(pca$x).
It would be great if any could help to plot the labels for the two categories or
even plot the points different color to make it easy to differentiate between the plots easily.
You need to specify your x and y coordinates a bit differently:
text(pca$x[1:18,1], pca$x[1:18,2] ...)
This means take the first 18 rows and the first column (which is PC1) for the x coord, etc.
I'm surprised what you did doesn't throw an error.
If you want the points themselves colored, you can do it this way:
plot(pca$x, main = "PC1 Vs PC2", col = c(rep("green", 18), rep("red", 18)))

rotate X axis labels 45 degrees on grouped bar plot R

How can I rotate the X axis labels 45 degrees on a grouped bar plot in R?
I have tried the solution suggested here but got something very messy, the labels seem to have been added multiple times (only showing the axis part to protect data privacy):
This solution (gridBase) was also unsuccessful for me, for some reason I get the following error:
"Cannot pop the top-level viewport (grid and graphics output mixed?)"
PS.
Most people seem to recommend this solution in R base but I am stuck with that too because I don't understand what data they are referring to (I need some kind of example data set to understand new command lines...).
Are these solutions not working because my barplot is a grouped barplot? Or should it work nevertheless? Any suggestions are welcome, I have been stuck for quite some time. Thank you.
[edit] On request I am adding the code that I used to generate the picture above (based on one of the text() solutions):
data <- #this is a matrix with 4 columns and 20 rows;
#colnames and rownames are specified.
#the barplot data is grouped by rows
lablist <- as.vector(colnames(data))
barplot(data, beside=TRUE, col=c("darkred","red","grey20","grey40"))
text(1:100, par("usr")[1], labels=lablist, srt=45, pos=1, xpd=TRUE)
I am not a base plot proficient, so maybe my solution is not very simple. I think that using ggplot2 is better here.
def.par <- par(no.readonly = TRUE)
## divide device into two rows and 1 column
## allocate figure 1 for barplot
## allocate figure 2 for barplot labels
## respect relations between widths and heights
nf <- layout(matrix(c(1,1,2,2),2,2,byrow = TRUE), c(1,3), c(3,1), TRUE)
layout.show(nf)
## barplot
par(mar = c(0,1,1,1))
set.seed(1)
nKol <- 8 ## you can change here but more than 11 cols
## the solution is not really readable
data <- matrix(sample(1:4,nKol*4,rep=TRUE),ncol=nKol)
xx <- barplot(data, beside=TRUE,
col=c("darkred","red","grey20","grey40"))
## labels , create d ummy plot for sacles
par(mar = c(1,1,0,1))
plot(seq_len(length(xx)),rep(1,length(xx)),type='n',axes=FALSE)
## Create some text labels
labels <- paste("Label", seq_len(ncol(xx)), sep = " ")
## Plot text labels with some rotation at the top of the current figure
text(seq_len(length(xx)),rep(1.4,length(xx)), srt = 90, adj = 1,
labels = labels, xpd = TRUE,cex=0.8,srt=60,
col=c("darkred","red","grey20","grey40"))
par(def.par) #- reset to default
Try the first answer:
x <- barplot(table(mtcars$cyl), xaxt="n")
labs <- paste(names(table(mtcars$cyl)), "cylinders")
text(cex=1, x=x-.25, y=-1.25, labs, xpd=TRUE, srt=45)
But change cex=1 to cex=.8 or .6 in the text() function:
text(cex=.6, x=x-.25, y=-1.25, labs, xpd=TRUE, srt=45)
In the picture you posted, it appears to me that the labels are just too big. cex sets the size of these labels.
I had the same problem with a grouped bar plot. I assume that you only want one label below each group. I may be wrong about this, since you don't state it explicitly, but this seems to be the case since your labels are repeated in image. In that case you can use the solution proposed by Stu although you have to apply colMeans to the x variable when you supply it to the text function:
x <- barplot(table(mtcars$cyl), xaxt="n")
labs <- paste(names(table(mtcars$cyl)), "cylinders")
text(cex=1, x=colMeans(x)-.25, y=-1.25, labs, xpd=TRUE, srt=45)

Scatter plot in R

I'm fairly new to r and I have to plot the scatter plot with:
residues1 residues2 coovariance
1 1 0.99613318
2 1 0.98771518
3 1 0.98681384
4 1 0.99225447
residue 1 and residue2 as x,y axis and the coovariance is to be color scale rather than height. I have previously used scatter plot 3d but don't know how to plot the third axis as a color scale. Please help .
Thanks
Vibhor
I'm not sure an x-y plot with color per column 3 is the best way to visualize this. If residues2 is a constant, prob. better to leave it out altogether and plot the other values against each other.
Perhaps you could adapt the following to your needs:
df1 <- data.frame(r1=seq(4), r2=rep(1,4),
c1=c(0.99613318, 0.98771518, 0.98681384, 0.99225447) )
### give order (for plotting)
df1 <- within(df1, c2 <- rank(c1))
### create blank plot
with(df1, plot(r1,r2, xlab="residues_1", ylab="residues_2", cex.lab=1.5))
### strongest red to largest color
with(df1, points(r1, r2, cex=15, pch=19, col = rev(heat.colors(4))[c2] ))
### make legend
l1 <- as.matrix(df1[ ,"c1"])
graphics::legend("topright", legend=l1, lty=1, title="covariance", lwd=3,
col = rev(heat.colors(4))[df1$c2], cex=2)
giving:
(I've made the image elements a bit oversize, and manually adjusted dimensions before saving as .png in order to display better on here).

Resources