color2D.matplot Legend in R - r

Does anyone know how to change the placement of the legend in color2D.matplot (plotrix)? I have a12 x 12 correlation matrix. I noticed I had to reverse the row names and change the margin to get the long names to fit. But now I am stumped on how to move the legend (without increasing the margin even more and making the graph look odd with so much white space at the bottom. Thanks!
cors<-cor(train)cellcol<-color.scale(cbind(cors,c(-1,rep(1,11))),c(0,1),0,c(1,0))[,1:12]
par(mar = c(10,8,4,2) + 0.1)
color2D.matplot(cors,cellcolors=cellcol,show.legend=TRUE,show.values=2,
axes=FALSE, xlab="",ylab="")
axis(1,at=0.5:11.5,las=2,labels=colnames(cors))
axis(2,at=0.5:11.5,las=2,labels=rev(rownames(cors)))

The help page says:
"If the default is not suitable, call color.legend separately." And then gives an example.
Based on a guess (in the absence of any information about "train" or "cors", you can try:
color.legend(0,13,6.5,14,legend=c(-1,-0.5,0,0.5,1),
rect.col=color.scale(cbind(cors,c(-1,rep(1,11))),c(0,1),0,c(1,0))[,1:12],
align="rb")

Related

How can I eliminate extra space in a stripchart in base R?

I have created a stripchart in R using the code below:
oldFaithful <- read.table("http://www.isi-stats.com/isi/data/prelim/OldFaithful1.txt", header = TRUE)
par(bty = "n") #Turns off plot border
stripchart(oldFaithful, #Name of the data frame we want to graph
method = "stack", #Stack the dots (no overlap)
pch = 20, #Use dots instead of squares (plot character)
at = 0, #Aligns dots along axis
xlim = c(40,100)) #Extends axis to include all data
The plot contains a large amount of extra space or whitespace at the top of the graph, as shown below.
Is there a way to eliminate the extra space at the top?
Short Answer
Add the argument offset=1, as in
stripchart(oldFaithful, offset=1, ...)
Long Answer
You really have to dig into the code of stripchart to figure this one out!
When you set a ylim by calling stripchart(oldFaithful, ylim=c(p,q)) or when you let stripchart use its defaults, it does in fact set the ylim when it creates the empty plotting area.
However, it then has to plot the points on that empty plotting area. When it does so, the y-values for the points at one x-value are specified as (1:n) * offset * csize. Here's the catch, csize is based on ylim[2], so the smaller you make the upper ylim, the smaller is csize, effectively leaving the space at the top of the chart no matter the value of ylim[2].
As a quick aside, notice that you can "mess with" ylim[1]. Try this:
stripchart(oldFaithful, ylim=c(2,10), pch=20, method="stack")
OK, back to solving your problem. There is a second reason that there is space at the top of the plot, and that second reason is offset. By default, offset=1/3 which (like csize) is "shrinking" down the height of the y-values of the points being plotted. You can negate this behavior be setting offset closer or equal to one, as in offset=0.9.

r - aligning x-axis image and base plot

When I try to align an image plot with a xy plot by their x-axis there is a small misalignment between the x-values. Can't figure out how to get rid of it!
Notice the misalignment of the vertical lines from the bottom plot with the x-axis on the top plot.
par(mfrow=c(2,1))
par(mar=c(0,5,5,5))
image(x=1:100,z=replicate(10, rnorm(100)))
par(mar=c(5,5,0,5))
par(xaxs="i")
plot(1:100,rnorm(100))
abline(v=1:100)
Gurus, help!! Thank you!!
PS: Could not figure it out with the post "plot-time-series-and-image-in-r-so-that-x-axis-labels-line-up-perfectly", still having issues!
The problem is that image draws data as a grid of cells which have a given width. If the length of x in image equals to nrow(z) then it specifies the midpoints of the cells. In your example this gives you rectangles centered around 1:100, effectively resulting in the x-axis covering the range from 0.5 to 100.5, which gives the observed misalignment.
In order to match the ranges in both plots you need to specify xlim to plot accordingly. In the following example I use n = 10 to make things more obvious.
par(mfrow=c(2,1))
par(mar=c(0,5,5,5))
image(x=1:n,z=replicate(10, rnorm(n)))
par(mar=c(5,5,0,5))
par(xaxs="i")
plot(1:n,rnorm(n), xlim=c(.5,n+.5))
abline(v=1:n)
Okay, so this is one of those things I had probably figured out on the past and then completely forgot about.
The trick is not only calling par(xaxs="i") but also enforcing both xlims!
par(mfrow=c(2,1))
par(mar=c(0,5,5,5))
image(x=1:100,z=replicate(10, rnorm(100)),xlim=c(0,100))
par(mar=c(5,5,0,5))
par(xaxs="i")
plot(1:100,rnorm(100),xlim=c(0,100))
abline(v=1:100)

Not able to decrease size of legend box R

I'm trying to display 4 plots in the same device window in R. I'm using Linux. However my output is far from pleasant to view.
As you can see the legend box is quite huge compared the size of the plot. I'm trying to decrease the size of the box; however I'm not able to do it. I've tried positioning the legend, box.lwd, cex, none of those gave me what I wanted.
Can anyone give me some pointers on how to decrease the size of the box of the legend?
Here is my R code:
require survival
survspec <- survfit(Surv(data1$YearEvent, data1$status) ~ data1$Vac, data1)
par(mfrow=c(2,2))
plot(survspec, mark.time=FALSE, xlab="Time (in years)", ylim=c(0.7, 1),
ylab="S(t)", col=c("royalblue", "violetred", "seagreen"))
legend(x="left",legend=c("Yes", "No", "NA"), lty=c(1, 1, 1),
col=c("royalblue", "violetred", "seagreen"))
The variable YearEvent corresponds to the x axis while the variable status is 0 or 1 and Vac can take three values. It's a Kaplan Meier plot, mainly used in survival analysis
All you need to do is use the cex set of parameters in your legend command. That will reduce the font size and I believe the symbol size (although you aren't displaying any symbols in this particular case), and thus the entire size of the legend box.
See ?par for details.
Please have a look at y.intersp parameter in legends() function. Thanks!

R How to build angled column headings above columns in heatmap.2: pass (text) plot to the layout?

I am very close to the heatmap I want, but I have been struggling for several days to figure out the headings problem. I want angled headings (such as 45 or 50 degrees) at the top of each column. I have already suppressed the dendrograms (for both columns and rows), and used the first column of my matrix (depth) as labels for the rows.
From my many, many searches on this issue, I see that mtext won't help me because the text cannot be rotated in mtext. Then I thought I could do it with text, but the column labels get overwritten onto the heatmap itself; they "disappear" (get covered) when the words reach the edge of the heatmap layout space. So I examined the layout used by heatmap (thanks very much to #Ian Sudbery), and it occurred to me that what I really need is a dedicated space in the layout for my column headings. I can allocate that space using the layout function, and I have done so in the code below. But I think the next step may involve getting inside the heatmap.2 code. Heatmap.2 calls four plots (two of which I have suppressed, the dendrograms). How do I make it call a fifth plot? And if that is possible, how do I tell it that I want to use text as my fifth "plot", where the text is my column headings, rotated 50deg?
Thanks very much for any ideas. Please forgive the clumsy way I've provided sample data in the code below; I am new to R and generally do not know the most elegant way to do most things.
par(oma=c(0.5,0.5,.5,0.5)) # outer margins of whole figure
lmat = rbind(c(3,5,5),c(2,1,1),c(0,4,0))
lwid = c(.08,.9, .1)
lhei = c(1,4,1.5)
Depth<-c("0m","20m","40m","60m","80m","100m")
Sept2008<-c(3,6,8,10,15,16)
March2010<-c(10,12,11,13,12,11)
Sept2010<-c(5,6,NA,8,11,13)
March2011<-c(4,6,10,NA,14,14)
Sept2011<-c(2,5,3,9,16,12)
heatmap_frame=data.frame(Depth=Depth,Sept2008=Sept2008,March2010=March2010,Sept2010=Sept2010, March2011=March2011, Sept2011=Sept2011)
row.names(heatmap_frame)<-heatmap_frame$Depth
heatmap_frame<-heatmap_frame[,-1]
heatmap_matrix <- as.matrix(heatmap_frame)
labCol=c("Sept 2008","March 2010","Sept 2010","March 2011","Sept 2011")
cexCol=1.1
heatmap <- heatmap.2(heatmap_matrix, dendrogram="none", trace="none",Rowv=NA, Colv=NA,
col = brewer.pal(9,"Blues"), scale="none", margins=c(2,5),labCol="",
lmat=lmat, lwid=lwid,lhei=lhei, density.info="none",key=TRUE)
# want to plot a fifth area, to use for col labels
# don't know how to pass a text line to the heatmap.2/layout/matrix to print as my fifth plot
mtext("Use for main title", side=3,outer=F,line=2.75, font=2, cex=1.25)
# testing the text function; did not work as desired
#text(x=1, y=1, labels="Label_1",xpd=T)
text(x=c(0,.2,.4,.6,.8), y=0.95, pos=3, srt=50, labels=labCol,xpd=T, cex=1)
Here's a hack that doesn't involve pulling apart the convoluted code of heatmap.2:
pos2 <- locator() #will return plotting coordinates after doing this:
# Shift focus to the graphics window by clicking on an edge
# Left-Click once where you want the first label to be centered
# Left-click again on the point where you want the last label centered
# Right-Click, then return focus to the console session window
pos2 <- structure(list(x = c(0.27149971320082, 0.858971646016485),
y = c(0.861365598392473, 0.857450478257082)),
.Names = c("x", "y"))
text(x=seq(pos2$x[1], pos2$x[2], len=5), y=rep(pos2$y[1],5) ,
srt=50, xpd=TRUE, adj = 0,
labels=c("Sept 2008","March 2010","Sept 2010",
"March 2011","Sept 2011") )
I don't know if you actually need the xpd in there, since it appears that after heatmap.2 is finished it returns the window to its native coordinates: [0,1]x[0,1]

Extending the scale of an axis

I have generated the following histogram in R:
I generated it using this hist() call:
hist(x[,1], xlab='t* (Transition Statistic)',
ylab='Proportion of Resamples (n = 10,000)',
main='Distribution of Resamples', col='lightblue',
prob=TRUE, ylim=c(0.00,0.05),xlim=c(1725,max(x[,1])+10))
Plus the following abline():
abline(v=1728,col=4,lty=1,lwd=2)
That vertical line indicates the actual location of a test statistic, which I am comparing to the results of permutation samples.
My question is this: as you can see, the x scale does not extend back to the vertical line. I would really like it to do so, because I think it looks odd otherwise. How can I make this happen?
I have already tried the xaxs="i" parameter, which has no effect. I have also tried making my own axis with axis() but this requires making both axes again from scratch, and the results don't look that great to me. So, I suspect there must be an easier way to do this. Is there? And, if not, can anyone suggest what axis() command might work well, assuming I want everything to look basically the same, but with the longer x scale?
The usual R plot draws a frame around the plot. To add this, do:
box()
after the plot.
If that isn't what you want, you need to suppress axis plotting and then add your own later.
hist(...., axes = FALSE) ## .... is where your other args go
axis(side = 2)
axis(side = 1, at = seq(1730, 1830, by = 20))
That won't go quite to the vertical line but may be close enough. If you want a tick at the vertical line, choose different tick marks, e.g.
axis(side = 1, at = seq(1725, 1835, by = 20))
Since R is using gaps of 20 for the x-axis here, you can get the extension you want using 1720 rather than 1725 for the lower limit , i.e. with xlim=c(1720,max(x[,1])+10) which would produce something like

Resources