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"))
Related
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)
I have to plot the following graph in R:
library(TTR)
x.date<-seq(1,num.years,by=20)
x.axis<-list(x1="1900",x2="1920",x3="1940",x4="1960",x5="1980",x6="2000")
plot(Annual.Mean.1, type="l",col="gray48",xaxt="n", xlab="Years",
ylab="Temperature")
grid()
axis(1,x.date,x.axis)
SMA.1<-SMA(Annual.Mean.1,n=10
par(new=TRUE)
lines(SMA.1,col="red",type="l",lwd="2",xaxt="n",yaxt="n",ann=FALSE)
SMA.2<-SMA(Annual.Mean.1,n=15)
par(new=TRUE)
lines(SMA.2,col="mediumpurple",type="l",lwd="2",xaxt="n",yaxt="n",ann=FALSE)
SMA.3<-SMA(Annual.Mean.1,n=20)
lines(SMA.3,col="blue",type="l",lwd="2",xaxt="n",yaxt="n",ann=FALSE)
legend("topleft",legend=c("Average Temperature","SMA 10 years","SMA 15 years","SMA 20 Years"),
text.col=c("black","red","mediumpurple","blue"),col=c("gray48","red","mediumpurple","blue"),
cex=0.7,lty=c(1,1,1,1))
The output is this:
In the above plot, the rectangle which contain the legend is very big; i would like to obtain a smaller rectangle, like in the below plot:
How to do this?
UPDATE
As suggested in the comments, I have modified my code, in order to make it reproducible by anyone:
library(TTR)
set.seed(1)
x.date<-seq(1,111,by=20)
x.axis<-list(x1="1900",x2="1920",x3="1940",x4="1960",x5="1980",x6="2000")
data<-runif(111,-3,3)
plot(data, type="l",col="gray48",xaxt="n",xlab="Years",
ylab="Temperature")
grid()
axis(1,x.date,x.axis)
SMA.1<-SMA(data,n=10)
par(new=TRUE)
lines(SMA.1,col="red",type="l",lwd="2",xaxt="n",yaxt="n",ann=FALSE)
SMA.2<-SMA(data,n=15)
par(new=TRUE)
lines(SMA.2,col="mediumpurple",type="l",lwd="2",xaxt="n",yaxt="n",ann=FALSE)
SMA.3<-SMA(data,n=20)
lines(SMA.3,col="blue",type="l",lwd="2",xaxt="n",yaxt="n",ann=FALSE)
legend("topleft",legend=c("Average Temperature","SMA 10 years","SMA 15 years","SMA 20 Years"),
text.col=c("black","red","mediumpurple","blue"),col=c("gray48","red","mediumpurple","blue"),
cex=0.7,lty=c(1,1,1,1))
I still having the same problem as explained above.
Reduce the value of your cex parameter in the legend call. You have it at cex=0.7. Try 0.6 or 0.5 (or lower) until you find the best size.
If that doesn't work, another approach is to just remove the box around the legend altogether with parameter bty = "n". If the background of the legend is blocking the lines in the graph, move the legend command up in your code so that it is drawn first and the lines are drawn over top of it.
How do I prevent the red line for the last distribution from being plotted outside of the area of the plot in the graph below?
chart http://i.minus.com/jRiGxDBVw6kjZ.jpeg
I generated the graph with the following code:
x <- seq(0,4,.1)
alpha_0 <- 2
beta_0 <- .2
hist(rexp(256, rate=1))
sample <- rexp(256, rate=1)
plot(x,dgamma(x, shape=alpha_0, rate=beta_0),type='l',col='black',ylim=c(0,2),main="Posteriors of Exponential Distribution", ylab='')
lines(x,dgamma(x, shape=alpha_0+4, rate=beta_0+sum(sample[1:4])),col='blue')
lines(x,dgamma(x, shape=alpha_0+8, rate=beta_0+sum(sample[1:8])),col='green')
lines(x,dgamma(x, shape=alpha_0+16, rate=beta_0+sum(sample[1:16])),col='orange')
lines(x,dgamma(x, shape=alpha_0+256, rate=beta_0+sum(sample[1:256])),col='red',)
legend(x=2.5,y=2, c("prior","n=4", "n=8", "n=16", 'n=256'), col = c('black', 'blue', 'green','orange' ,'red'),lty=c(1,1,1,1))
Sorry, seems like a pretty simple fix, I just couldn't figure it out from the documentation. Thanks for your help.
Yes, as Joran mentioned, it was graphing the line outside of the plot area because I ran par(xpd=TRUE) earlier in the session to try to put the legend outside. I simply ran par(xpd=FALSE) and it solved the problem.
Hello I am trying to create a stacked barplot using the following code:
test <- as.matrix(read.csv(file="test4.csv",sep=",",head=TRUE))
test <- test[,2:ncol(test)]
pdf(file="test.pdf", height=4, width=6)
par(lwd = 0.3)
barplot(test, space=0.4, xaxt='n', ann=FALSE)
axis(1, cex.axis=0.25, las=2, at=1:ncol(test), space=0.4, labels=colnames(test))
dev.off()
And I get:
As you can see the labels in the x-axis do not match the bars in the plot. Also, the ticks are huge.
Can you guys help me beautify the x axis? Thanks so much
Try storing the returned value of the call to barplot() in a named object, and then passing that in to the at= argument of axis():
xLabLocs <- barplot(test, space=0.4, xaxt='n', ann=FALSE)
axis(1, cex.axis=0.25, las=2, at=xLabLocs,
space=0.4, labels=colnames(test))
This may look odd, but it is explained in the Value section of the ?barplot help file:
Value:
A numeric vector (or matrix, when ‘beside = TRUE’), say ‘mp’,
giving the coordinates of _all_ the bar midpoints drawn, useful
for adding to the graph.
You just made the (easy enough to make) mistake of assuming that the x-axis coordinates of the bar centers are at 1:n, where n is the number of bars. That's not necessarily true, so it's nice that a single call to barplot() will both: (a) plot the bar plot as its side effect; and (b) return the necessary x-axis coordinates as its return value.
I used the information from this post to create a histogram with logarithmic scale:
Histogram with Logarithmic Scale
However, the output from plot looks nothing like the output from hist. Does anyone know how to configure the output from plot to resemble the output from hist? Thanks for the help.
A simplified, reproducible version of the linked answer is
x <- rlnorm(1000)
hx <- hist(x, plot=FALSE)
plot(hx$counts, type="h", log="y", lwd=10, lend="square")
To get the axes looking more "hist-like", replace the last line with
plot(hx$counts, type="h", log="y", lwd=10, lend="square", axes = FALSE)
Axis(side=1)
Axis(side=2)
Getting the bars to join up is going to be a nightmare using this method. I suggest using trial and error with values of lwd (in this example, 34 is somewhere close to looking right), or learning to use lattice or ggplot.
EDIT:
You can't set a border colour, because the bars aren't really rectangles – they are just fat lines. We can fake the border effect by drawing slightly thinner lines over the top. The updated code is
par(lend="square")
bordercol <- "blue"
fillcol <- "pink"
linewidth <- 24
plot(hx$counts, type="h", log="y", lwd=linewidth, col=bordercol, axes = FALSE)
lines(hx$counts, type="h", lwd=linewidth-2, col=fillcol)
Axis(side=1)
Axis(side=2)
How about using ggplot2?
x <- rnorm(1000)
qplot(x) + scale_y_log10()
But I agree with Hadley's comment on the other post that having a histogram with a log scale seems weird to me =).