Aligning Text within Legend with Example Code - r

I am wanting to get the cleanest look using this code chunk which overlays my plot in R
legend(130, 0.0150, legend = c(paste0("Large diameter ", format(center, digits=6)),
paste0("Minimum ", format(min2, digits=6))),
bty = "n")
Notice the large white spaces. But this achieves the effect I want
But I know there's a better way to do this! I additionally want to add more descriptive statistics to the plot and this has to be a very inefficient way of doing it. So, what's the best way to align the text and numbers? Any way to beautify to this further? Thanks all!

You could just print two legends side by side.
Example
Example plot:
curve(cos(x)/100, xlim=c(0, 250), ylim=c(0, .02), col="blue")
center <- 135.873; min2 <- 86.3301 # values
Legend:
legend(130, 0.0150, legend=c("Large diameter", "Minimum"), bty="n")
legend(200, 0.0150, legend=c(format(center, digits=6),
format(min2, digits=6)), bty="n")

Related

How to change heatmap column labels to symbols in R

As indicated in the title above, I want to change the column labels in the heatmap figure produced by heatmap.2 from package gplots in R to symbols rather than text. May I know if it is possible, and if so, how to do it?
This is a sample code to generate heatmap using heatmap.2:
library(gplots)
data<-sample(1:100,size=80)
M<-matrix(data,nrow=10,ncol=8)
colnames(M)<-c("W1_1","W1_2","W1_3","W1_4","B1_1","B1_2","B1_3","B1_4")
heatmap.2(M, trace="none", dendrogram="none")
This is the heatmap result:
In this case, the column labels are "W1_1","W1_2","W1_3","W1_4","B1_1","B1_2","B1_3","B1_4". May I know If it is possible to use two symbols to represent W1 and B1 group respectively and show in the final figure.
I have attached a sample below (changed via photoshop):
Thanks in advance for all the helps!
Here's another possibility with standard image function:
op <- par(mar=c(4,2,2,4))
image(seq(nrow(M)), seq(ncol(M)), M, axes=F, xlab="", ylab="")
axis(side=4, at=seq(ncol(M)))
par(xpd=TRUE)
points(seq(nrow(M)), rep(0, nrow(M)),
pch=c(16, 15), col=c("cyan", "pink"), cex=2
)
par(op)

Legend dynamically populated

I have plotted a histogram in R and marked quantiles using abline() in vertical intervals. However, I want to plot a legend that shows the corresponding values to the quantiles together with the quantile interval itself.
The current legend is almost there as you can see if you run the example code below. But I can't seem to succeed at aligning the legend interval with its corresponding value and colored line symbol. I tried to use a data.frame() to achieve this but it didn't work out.
Any tips or suggestions will be very much appreciated.
x<-1:100
quantiles_x<-quantile(x)
hist(x)
abline(v=quantiles_x, col=c("blue", "green","red","yellow","black"))
legend('topright', legend=c(names(quantiles_x), levels(factor(quantiles_x))), lwd=1, col=c("blue","green","red","yellow","black"))
Something like this??
x<-1:100
quantiles_x<-quantile(x)
hist(x)
abline(v=quantiles_x, col=c("blue", "green","red","yellow","black"))
labels <- paste(names(quantiles_x), "[",quantiles_x,"]")
legend('topright', legend=labels, lwd=1,
col=c("blue","green","red","yellow","black"))

R-plot a centered legend at outer margins of multiple plots

I want to plot a centered legend outside of the plotting area in a device having multiple plots. There has been many questions (with slight variations) asked in SO about changing the position of legend in a R plot.
For example:
1) R - Common title and legend for combined plots
2) Common legend for multiple plots in R
3) Plot a legend outside of the plotting area in base graphics?
etc.
Now what I understood from the above questions is that I got to set the option xpd = T or xpd = NAto plot legends at the outer margins. However when I try this, it somehow does not work for me ..
par(mfrow=c(1,2),oma=c(0,3,0,0),xpd=TRUE)
plot(c(5,10),col=c("red","blue"),pch=20,cex=2,bty="n",xlab="",ylab="")
barplot(c(5,10),col=c("red","blue"))
mtext(text="My two plots",side=3,cex=2,outer=TRUE,line=-3)
legend("top",legend=c("A", "B"),fill=c("red","blue"),ncol=2,xpd=NA,bty="n") # Option 1
legend(x=0.01,y=11,legend=c("A", "B"),fill=c("red","blue"),ncol=2,xpd=TRUE,bty="n") # Option 2
Now my question is, how does xpd exactly work ? as I am unable to figure out why shouldn't the legend not be placed outside the plot area with xpd=T.
I apologize in advance if some consider this as a duplicate of the above questions !!
Help is much appreciated
Ashwin
Option #1 is likely the route you should take, with xpd=NA. It does not automatically place the legend in the outer margins, but it allows you to place the legend anywhere you want. So, for example, you could use this code to place the legend at the top of the page, approximately centered.
legend(x=-1.6, y=11.6, legend=c("A", "B"), fill=c("red", "blue"), ncol=2, xpd=NA, bty="n")
I chose these x and y values by trial and error. But, you could define a function that overlays a single (invisible) plot on top of the ones you created. Then you can use legend("top", ...). For example
reset <- function() {
par(mfrow=c(1, 1), oma=rep(0, 4), mar=rep(0, 4), new=TRUE)
plot(0:1, 0:1, type="n", xlab="", ylab="", axes=FALSE)
}
reset()
legend("top", legend=c("A", "B"), fill=c("red", "blue"), ncol=2, bty="n")
I also had a hard time to get coordinates on the margins. I think I found a solution, you can specify coordinates for the legend using:
getCoords() function.
Look also to legend_margin function from plotfunctions package.
So combining the solution from Jean V. Adams with one of these functions should get you there.
Hope that works :)

Plot multiple barplots on one plot, but bars dont overlap R

If I wanted to do this with the bars of the different calls to barplot(add=T) overlapping, that's fine and dandy. But say I want tthem to be plotted on the same plot, but with the first call having a ylim from 0:1 then the second call from 1:2 etc. I tried:
for(i in 1:length(files)) {
file <- as.matrix(read.table(files[i], header=F, sep=" ") )
if(i==1) barplot(file, beside=T, col=1:i, border=NA, ylim = c(0,length(files)))
if(i>1) barplot(file, beside=T, col=1:i, border=NA, ylim = c(i-1,i) ,xpd=T, add=T)
}
but that overlays them. How can I do it so that theyre on the same image but not overlapping if that makes sense. I envisage something like this http://img585.imageshack.us/img585/5439/romak13.png
If you're doing something like this, I'd recommend using ggplot2, as it's much easier.
Here's some sample code:
library(ggplot2)
data(diamonds)
ggplot(diamonds,aes(x=carat,y=price,fill=color))+
geom_histogram(stat='identity')+
facet_grid('cut~.',scale='free')+labs("Graph Title")
The output looks like this:
The interpretation of this particular graph is a bit strange, considering the nature of the data set, but if you follow the same format, you should be able to get a decent-looking graph. If anyone has any better data examples, let me know.

Legend box width not correct when using par

I have the problem , that my legend is too large, my code:
par(mfrow=c(1,2))
hist(alvsloss,breaks = 100, freq=F,main="Histogramm,
density curve (gaussian kernel) \n and fitted normal distribution of Allianz simple losses ",xlim=c(-0.15,0.15),xlab="loss",ylab="density",cex.axis=1.2,cex.lab=1.2)
lines(density(alvsloss), col="black", lwd=2)
curve(dnorm(x, mean = mean(alvsloss), sd = sd(alvsloss)), add=TRUE, col="black",lwd=2,lty="dotted")
legend(-0.155, 30, c("(Gaussian) Kernel density","fitted normal distribution"),lwd=2, cex=0.8,
col=c("black","black"), lty=1:2)
qqnorm(alvsloss,main="normal QQ Plot",cex.axis=1.2,cex.lab=1.2)
qqline(alvsloss)
This gives the following picture:
The problem is, that the legend on the left is too big, how can I control the width of the box? The box is way too large.
data can be found here: http://uploadeasy.net/upload/ocafq.rar
The white space on the right of you legend tells me that you manually widened your plot window. Legends do not scale well when it comes to manual re-sizing.
The solution is opening a plot of the exact size you need before plotting. In Windows, this is done with windows(width=10, height=8). Units are in inches. The surrounding box should now be tighter with the text.
If this is still not satisfactory, you should try:
Reducing the font size of the legend cex=0.7
Removing the box around the legend bty = "n" and using \n to
split your legend onto several lines
You can put your legend even more on the left using "topleft"
instead of coordinates
Here's how I would do it:
legend("topleft",
legend=c("(Gaussian)\nKernel\ndensity","Fitted\nnormal\ndistribution\n"),
bty = "n",lwd=2, cex=0.7, col=c("black","black"), lty=1:2)

Resources