I'm trying to create a stripplot in which the name of my parameters on the x axis are greek letters. It is quite logical then that I want my plot to be label with greek letters and not "theta", "rho" and "tau" subscripts. My strategy is to hide the original labels and plot the greek letters on top. The following example shows what I have tried so far:
library(lattice)
data <- data.frame(Parameters=c("theta","rho","tau"),val1=c(1,2,4),val2=c(2,3,4))
png("plot.png")
stripplot(val1 + val2 ~ Parameters, data = data, pch=c(1,2), cex=2,
scales=list(cex=c(0,1.5)),
xlab=c(expression(rho),expression(tau),expression(theta)),
ylab=NULL,
xaxt='n',
)
dev.off()
But this piece of code weirdly eliminates the labels in the y axis too.
Try 1:
I also followed the advice in How to hide x-axis in lattice R but the results preserves the names in the x-axis.
Try 2:
How can I eliminate ONLY the labels on the x-axis without altering the y axis?
Have a look at the help page for ?stripplot, in particular the
scales argument.
Generally a list determining how the x- and y-axes (tick marks and labels) are drawn.
So use this argument to pass the size and labels argument for the x-axis.
stripplot(val1 + val2 ~ Parameters, data = dat, pch=c(1,2), cex=2,
scales=list(x=list(cex=1.5,
labels=c(expression(rho),expression(tau),expression(theta))
)))
This is clunky but would help if you had many x-axis elements.
labels=as.expression(sapply(levels(dat$Parameters), function(x) as.name(x)))
or
labels=parse(text=as.character(sort(dat$Parameters)))
library(lattice)
data <- data.frame(Parameters=c("theta","rho","tau"),val1=c(1,2,4),val2=c(2,3,4))
png("plot.png")
stripplot(val1 + val2 ~ Parameters, data = data, pch=c(1,2), cex=2,
scales=list(cex=c(0,1.5)),
xlab=c(expression(rho),expression(tau),expression(theta)),
xaxt='n',
)
dev.off()
Related
I am working in R and I have to make many boxplots. This is a visualization of group differences. I want to relabel the x-axis to only have one title instead of five (one for each subplot). My biggest problem is that I also want the y-axis of all the subplots to have different labels.
This is what I tried so far:
par(mfrow=c(1,5))
lapply(NEW8[,c("gawayf", "humf", "sgamesf", "swtoyf", "kissf")],
function(x) boxplot(x ~ NEW8$PAPA_p4_adhd,col=rainbow(2),
names=c("CN","ADHD"),
ylab=c("gawayf", "humf", "sgamesf", "swtoyf", "kissf")))
All the y-labels are added to each subplots so each subplots has 5 lines of y-axis labels (gawayf, humf, sgamef, swtoyf, kissf), and each plot says what data was used to create the boxplot (PAPA_P4_ADHD).
I want each plots to only have the corresponding y-axis label and the x-axis to have 1 label for all five plots.
This is my current output:
Thank you very much
Instead of lapply try mapply - that will allow to pass different argument to each function call:
par(mfrow=c(1,5))
myBox <- function(x, y, ...) boxplot(x ~ y, col=rainbow(2), names=c("CN", "ADHA"), ...)
mapply(myBox,
x = NEW8[,c("gawayf", "humf", "sgamesf", "swtoyf", "kissf")],
y = list(NEW8$PAPA_p4_adhd), # we make this a list so it has length(1)
ylab = c("gawayf", "humf", "sgamesf", "swtoyf", "kissf"),
xlab = "" # empty x-lab
)
For x-lab you will have to do a trick - start a new empty plot that overlays all of the plots, and only add x-axis:
par(fig=c(0,1,0,1), oma=c(0,0,0,0), mar=par("mar"), new=TRUE)
plot.new()
title(xlab="my x-axis")
NOTE: I didn't try to run this code myself, if anything here doesn't work - please leave a comment and will try to address it.
I'm building a plot in R and I have used the plot() function, with log="y" parameter.
Does that mean that ONLY the y-axis labels will be converted in log scale OR that also the y-coordinates of my data will be converted in log-scale?
Thank you
When using log = "y" it plots the log-transformed y-values with the labels on the original scale -- the opposite of what you seem to suggest.
Compare these three plots:
x <- rnorm(50)
y <- 2*exp(x) + rexp(50)
plot(x, y) # y-scale, y-scale-labels
plot(x, y, log = "y") # log-y-scale, y-scale-labels
plot(x, log(y)) # log-y-scale, log-y-scale labels
Notice that the last two plots only differs in the y-axis labels. Both are still correct as the axis titles are also different.
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)
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)
While plotting histogarm, scatterplots and other plots with axes scaled to logarithmic scale in R, how is it possible to use labels such as 10^-1 10^0 10^1 10^2 10^3 and so on instead of the axes showing just -1, 0, 1, 2, 3 etc. What parameters should be added to the commands such as hist(), plot() etc?
Apart from the solution of ggplot2 (see gsk3's comment), I would like to add that this happens automatically in plot() as well when using the correct arguments, eg :
x <- 1:10
y <- exp(1:10)
plot(x,y,log="y")
You can use the parameter log="x" for the X axis, or log="xy" for both.
If you want to format the numbers, or you have the data in log format, you can do a workaround using axis(). Some interesting functions :
axTicks(x) gives you the location of the ticks on the X-axis (x=1) or Y-axis (x=2)
bquote() converts expressions to language, but can replace a variable with its value. More information on bquote() in the question Latex and variables in plot label in R? .
as.expression() makes the language object coming from bquote() an expression. This allows axis() to do the formatting as explained in ?plotmath. It can't do so with language objects.
An example for nice formatting :
x <- y <- 1:10
plot(x,y,yaxt="n")
aty <- axTicks(2)
labels <- sapply(aty,function(i)
as.expression(bquote(10^ .(i)))
)
axis(2,at=aty,labels=labels)
Which gives
Here is a different way to draw this type of axis:
plot(NA, xlim=c(0,10), ylim=c(1, 10^4), xlab="x", ylab="y", log="y", yaxt="n")
at.y <- outer(1:9, 10^(0:4))
lab.y <- ifelse(log10(at.y) %% 1 == 0, at.y, NA)
axis(2, at=at.y, labels=lab.y, las=1)
EDIT: This is also solved in latticeExtra with scale.components
In ggplot2 you just can add a
... +
scale_x_log10() +
scale_y_log10(limits = c(1e-4,1), breaks=c(1e-4,1e-3,1e-2,0.1,1)) + ...
to scale your axis, Label them and add custom breaks.