Combining multiple complex plots as panels in a single figure - r

Introduction by #backlin
Multiple simple plots can combined as panels in a single figure by using layout or par(mfrow=...). However, more complex plots tend to setup their own panel layout internally disabling them from being used as panels. Is there a way to create a nested layout and encapsulating a complex plot into a single panel?
I have a feeling the grid package can accomplish this, e.g. by ploting the panels in separate viewports, but haven't been able to figure out how. Here is a toy example to demonstrate the problem:
my.plot <- function(){
a <- matrix(rnorm(100), 10, 10)
plot.new()
par(mfrow=c(2,2))
plot(1:10, runif(10))
plot(hclust(dist(a)))
barplot(apply(a, 2, mean))
image(a)
}
layout(matrix(1:4, 2, 2))
for(i in 1:4) my.plot()
# How to avoid reseting the outer layout when calling `my.plot`?
Original question by #alittleboy
I use the heatmap.2 function in the gplots package to generate heatmaps. Here is a sample code for a single heatmap:
library(gplots)
row.scaled.expr <- matrix(sample(1:10000),nrow=1000,ncol=10)
heatmap.2(row.scaled.expr, dendrogram ='row',
Colv=FALSE, col=greenred(800),
key=FALSE, keysize=1.0, symkey=FALSE, density.info='none',
trace='none', colsep=1:10,
sepcolor='white', sepwidth=0.05,
scale="none",cexRow=0.2,cexCol=2,
labCol = colnames(row.scaled.expr),
hclustfun=function(c){hclust(c, method='mcquitty')},
lmat=rbind( c(0, 3), c(2,1), c(0,4) ), lhei=c(0.25, 4, 0.25 ),
)
However, since I want to compare multiple heatmaps in a single plot, I use par(mfrow=c(2,2)) and then call heatmap.2 four times, i.e.
row.scaled.expr <- matrix(sample(1:10000),nrow=1000,ncol=10)
arr <- array(data=row.scaled.expr, dim=c(dim(row.scaled.expr),4))
par(mfrow=c(2,2))
for (i in 1:4)
heatmap.2(arr[ , ,i], dendrogram ='row',
Colv=FALSE, col=greenred(800),
key=FALSE, keysize=1.0, symkey=FALSE, density.info='none',
trace='none', colsep=1:10,
sepcolor='white', sepwidth=0.05,
scale="none",cexRow=0.2,cexCol=2,
labCol = colnames(arr[ , ,i]),
hclustfun=function(c){hclust(c, method='mcquitty')},
lmat=rbind( c(0, 3), c(2,1), c(0,4) ), lhei=c(0.25, 4, 0.25 ),
)
However, the result is NOT four heatmaps in a single plot, but four separate heatmaps. In other words, if I use pdf() to output the result, the file is four pages instead of one. Do I need to change any parameters somewhere? Thank you so much!

Okay. I suppose this question has been sitting unanswered for enough time that the long answer should be written up.
The answer to most difficult graphics issues is (as #backlin suggests) the raw use of the 'grid' package. Many prebuilt graphics packages override all current viewports and plot device settings, so if you want something done a very specific way, you have to build it yourself.
I recommend picking up Paul Murrell's book "R Graphics" and going over the chapter on the 'grid' package. It's a crazy useful book, and a copy sits on my desk all the time.
For your heatmap, I've written up a quick primer that will get you started quickly.
Functions to know
grid.newpage() This initializes the plotting device. Use it without parameters.
grid.rect() This draws a rectangle. Your heatmap is basically just a giant set of colored rectangles, so this will be bulk of your graphic. It works like so: grid.rect(x=x_Position, y=y_Position, width=width_Value, height=height_Value, gp=gpar(col=section_Color, fill=section_Color), just=c("left", "bottom"), default.units="native") The 'just' argument specifies which point of the rectangle will sit on your specified (x, y) coordinates.
grid.text() This draws text. It works like so: grid.text("Label Text", x_Value, y_Value, gp=gpar(col=color_Value, cex=font_Size), just=c("right","center"), rot=rot_Degrees, default.units="native")
grid.lines() This draws a line. It works like so: grid.lines(c(x_Start,x_End), c(y_Start, y_End), gp=gpar(col=color_Value), default.units="native")
dataViewport() This defines the attributes of a plotting window, which 'grid' refers to as a "viewport." Use it like so: pushViewport(dataViewport(xData=x_Data, yData=y_Data, xscale=c(x_Min, x_Max), yscale=c(y_Min, y_Max), x=x_Value, y=y_Value, width=width_Value, height=height_Value, just=c("left","center"))) There is some stuff to keep in mind here... see the more detailed explanation of viewports.
pushViewport() This is used to initialize a veiwport. You wrap this around a viewport definition to actually execute the viewport, like so: pushViewport(dataViewport([stuff in here]))
popViewport() This finalizes a viewport and moves you up one level in the hierarchy of viewports. See the more detailed explanation of viewports.
Viewports in a nutshell
Viewports are temporary drawing spaces that define where and how 'grid' objects will be drawn. Everything inside the viewport is drawn relative to the viewport. If the viewport is rotated, everything inside will be rotated. Viewports can be nested, can overlap, and are almost infinitely flexible, with one exception: they are always a rectangle.
Something that messes a lot of people up initially is the coordinate system. Every viewport, including the initial 'grid.newpage()' viewport, goes from 0 to 1 on both the x and y axes. The origin (0,0) is the far lower left corner, and the max (1,1) is the far upper right corner. This is the "npc" unit system, and everything that doesn't have a set of units specified will likely end up being drawn according to this system. This means two things for you:
Use the "npc" system when specifying viewport sizes and locations. Just assume that your viewports have to use the "npc" coordinates, and you'll save yourself a LOT of hassle. This means if I want to draw two plots next to each other, the definitions for the two viewports would look something like:
viewport(x=0, y=0, width=0.5, height=1, just=c("left","lower")) and
viewport(x=0.5, y=0, width=0.5, height=1, just=c("left","lower"))
If your viewport has a different coordinate system (for example a viewport for plotting a graph), then you will need to specify the 'default.units' argument for every 'grid' object you draw. For instance, if you tried to plot a point at (2,4) you would never see the point, because it would be far off-screen. Specifying default.units="native" would tell that point to use the viewport's own coordinate system and would draw the point correctly.
Viewports can be navigated and written to directly, but unless you're doing something very automated, it is easier to specify a viewport, draw inside it, and then "pop" (finalize) the viewport. This returns you to the parent viewport, and you can start on the next viewport. Popping each viewport is a clutter-free approach and will suit most purposes (and make it easier to debug!).
The 'dataViewport' function is all important when plotting a graph. This is a special type of viewport that handles all of the coordinates and scales for you, as long as you tell it what data you are using. This is the one I use for any plotting area. When I first started using the 'grid' package, I adjusted all of my values to fit the "npc" coordinate system, but that was a mistake! The 'dataViewport' function makes is all easy as long as you remember to use the "native" units for each drawing item.
Disclaimer
Data visualization is my forte, and I don't mind spending half a day scripting up a good visual. The 'grid' package allows me to create quite sophisticated visuals faster than anything else I found. I script up my visuals as functions, so I can load various data quickly. I couldn't be happier.
However, if you don't like to script things, 'grid' will be your enemy. Also, if you consider half a day to be too much time for a visual, then 'grid' won't help you too much. The (in)famous 'ggplot2' package is what most people settle on, and I heartily recommend it, even though I don't personally find it useful.
If someone wants help learning 'grid' graphics, I'm more than willing to help teach. It has completely revolutionized my ability to create fast, intelligent, and good-looking data visuals.

The gridGraphics package might help,
library(gridGraphics)
library(grid)
grab_grob <- function(){
grid.echo()
grid.grab()
}
arr <- replicate(4, matrix(sample(1:100),nrow=10,ncol=10), simplify = FALSE)
library(gplots)
gl <- lapply(1:4, function(i){
heatmap.2(arr[[i]], dendrogram ='row',
Colv=FALSE, col=greenred(800),
key=FALSE, keysize=1.0, symkey=FALSE, density.info='none',
trace='none', colsep=1:10,
sepcolor='white', sepwidth=0.05,
scale="none",cexRow=0.2,cexCol=2,
labCol = colnames(arr[[i]]),
hclustfun=function(c){hclust(c, method='mcquitty')},
lmat=rbind( c(0, 3), c(2,1), c(0,4) ), lhei=c(0.25, 4, 0.25 ),
)
grab_grob()
})
grid.newpage()
library(gridExtra)
grid.arrange(grobs=gl, ncol=2, clip=TRUE)

I struggled with a similar problem and came up with a solution that is very easy but requires imagemagick installed. The idea is to plot the heatmaps to separate files and then combine them with the montage command:
library(gplots)
row.scaled.expr <- matrix(sample(1:10000),nrow=1000,ncol=10)
arr <- array(data=row.scaled.expr, dim=c(dim(row.scaled.expr),4))
par(mfrow=c(2,2))
for (i in 1:4) {
ifile <- paste0(i,'_heatmap.pdf')
pdf(ifile)
heatmap.2(arr[ , ,i], dendrogram ='row',
Colv=FALSE, col=greenred(800),
key=FALSE, keysize=1.0, symkey=FALSE, density.info='none',
trace='none', colsep=1:10,
sepcolor='white', sepwidth=0.05,
scale="none",cexRow=0.2,cexCol=2,
labCol = colnames(arr[ , ,i]),
hclustfun=function(c){hclust(c, method='mcquitty')},
lmat=rbind( c(0, 3), c(2,1), c(0,4) ), lhei=c(0.25, 4, 0.25 ),
)
dev.off()
}
system('montage -geometry 100% -tile 2x2 ./*_heatmap.pdf outfile.pdf')

Just as Dinre said, the "grid" pacakge can handle all complex plots. For the original question by #alittleboy, I think the package "ComplexHeatmap" (which is also base on grid) from Bionconductor can be a nice solution (http://www.bioconductor.org/packages/release/bioc/vignettes/ComplexHeatmap/inst/doc/ComplexHeatmap.html)

Related

igraph ggplot rStudio How can I make lines between nodes longer and add arrows? Also how can I make the legend smaller?

I have a really wordy network plot. I am basically trying to have it function as a sort of flow chart. I am trying to make its aesthetics both functional and pleasing, but I am having a difficult time. The legend's text is way too large and there is not enough space in the network for everything to be spaced out properly. Also, I want to make the background a different color.
The only solutions I have been able to find, however, require the ggnet2 package, but when I try to install the ggnet2 package, it says I cannot install that on this version of rStudio. When I tried to update my rStudio, it says that I have the most recent version of rStudio. I do not know what else to try.
Any help would be much appreciated! This is my code:
library(igraph)
library(RColorBrewer)
links <- data.frame(
source=c("Pubertal Hormones, Timing, and Development","Pubertal Hormones, Timing, and Development","Pubertal Hormones, Timing, and Development","Pubertal Hormones, Timing, and Development","Genetic Vulnerability","Genetic Vulnerability","Temperament","Temperament","Depressogenic Vulnerability","Negative Cognitive Style","Negative Cognitive Style","Objectified Body Consciousness","Objectifed Body Consciousness","Rumination","Peer Sexual Harassment","Peer Sexual Harassment"),
target=c("Genetic Vulnerability","Objectified Body Consciousness","Peer Sexual Harassment","Depressogenic Vulnerability","Temperament","Depressogenic Vulnerability","Negative Cognitive Style","Depressogenic Vulnerability","Gender Difference in Depression","Rumination","Depressogenic Vulnerability","Rumination","Depressogenic Vulnerability","Depressogenic Vulnerability","Objectified Body Consciousness","Gender Difference in Depression"),
importance=(sample(1:4, 16, replace=T))
)
V = c(links$source,
links$target) %>%
unique()
nodes <- data.frame( name=V,
carac=c(
rep("Biological Vulnerability",2),rep("Affective Vulnerability",3),rep("Cognitive Vulnerability",3),rep("Negative Life Events",2)) )
network <- graph_from_data_frame(d=links, vertices=nodes, directed=F)
coul <- brewer.pal(4, "Set3")
my_color <- coul[as.numeric(as.factor(V(network)$carac))]
plot(network, vertex.color=my_color,vertex.shape=c("vrectangle"),vertex.size=c(150),vertex.label.cex=c(0.5))
legend("bottom", legend=levels(as.factor(V(network)$carac)) , col = coul , bty = "n", pch=20 , pt.cex = 3, cex = 1, text.col=coul , horiz = TRUE, inset = c(0.1, 0.1))
With a small graph like this, you can customize the layout so that things look nicer. We'll just step through the problems one at a time. Let's start from your plot statement, but let's make it reproducible by setting the random seed.
set.seed(123)
plot(network, vertex.color=my_color,vertex.shape=c("vrectangle"),
vertex.size=c(150),vertex.label.cex=c(0.5))
The biggest problem is that the plot does not use all of the space in the graphics window. You can adjust that some with the margin parameter. When I do that, the boxes seem too big, so I will make them a bit smaller at the same time and also change the text size to match the new boxes.
set.seed(123)
LO = layout_nicely(network)
plot(network, layout=LO, margin=-0.6, vertex.color=my_color,
vertex.shape=c("vrectangle"), vertex.size=c(100),
vertex.label.cex=c(0.7))
OK, this is better, but there still are some problems. First, the box for "Pubertal Hormones, Timing, and Development" is too small. We can adjust that by using a vector of vertex sizes. When we change that, there are some other changes in the plot, so let's just make that one change first.
VS = rep(100, vcount(network))
VS[1] = 150
plot(network, layout=LO, margin=-0.7, vertex.color=my_color,
vertex.shape=c("vrectangle"), vertex.size=VS,
vertex.label.cex=c(0.7))
Next, some of the boxes overlap. We can fix those by editing the layout matrix. This matrix is just the x,y coordinates at which to plot the nodes. I just looked at the matrix and adjusted the positions a little.
LO[1,] = c(6.3,7.3)
LO[4,] = c(5.4,6.7)
LO[5,] = c(5,5.5)
LO[7,] = c(7.4,6.8)
LO[8,] = c(5.1,6.2)
LO[9,] = c(5.2,8.4)
LO[10,] = c(7,8.3)
plot(network, layout=LO, margin=-0.7, vertex.color=my_color,
vertex.shape=c("vrectangle"), vertex.size=VS,
vertex.label.cex=c(0.7))
This is pretty good. More could be done, but I think the method is clear, so I will leave any additional aesthetic adjustments of the nodes to you.
Now to finish up, you wanted to adjust the background color. You can do that (before plotting) by setting bg using par. The final version is:
par(bg="lightblue1")
plot(network, layout=LO, margin=-0.7, vertex.color=my_color,
vertex.shape=c("vrectangle"), vertex.size=VS,
vertex.label.cex=c(0.7))

Controlling margins in a genoPlotR plot_gene_map

I'm producing a plot_gene_map figure by the genoPlotR R package, which gives a horizontal phylogenetic tree where aligned with each leaf is a genomic segment.
Here's a simple example that illustrates my usage and problem:
The plot_gene_map function requires an ade4s' package phylog object which represents the phylogenetic tree:
tree <- ade4::newick2phylog("(((A:0.08,B:0.075):0.028,(C:0.06,D:0.06):0.05):0.0055,E:0.1);")
A list of genoPlotR's dna_seg objects (which are essentially data.frames with specific columns), where the names of the list elements have to match the names of the leaves of tree:
dna.segs.list <- list(A=genoPlotR::as.dna_seg(data.frame(name=paste0("VERY.LONG.NAME.A.",1:10),start=seq(1,91,10),end=seq(5,95,10),strand=1,col="black",ly=1,lwd=1,pch=1,cex=1,gene_type="blocks",fill="red")),
B=genoPlotR::as.dna_seg(data.frame(name=paste0("VERY.LONG.NAME.B.",1:10),start=seq(1,91,10),end=seq(5,95,10),strand=1,col="black",ly=1,lwd=1,pch=1,cex=1,gene_type="blocks",fill="blue")),
C=genoPlotR::as.dna_seg(data.frame(name=paste0("VERY.LONG.NAME.C.",1:10),start=seq(1,91,10),end=seq(5,95,10),strand=1,col="black",ly=1,lwd=1,pch=1,cex=1,gene_type="blocks",fill="green")),
D=genoPlotR::as.dna_seg(data.frame(name=paste0("VERY.LONG.NAME.D.",1:10),start=seq(1,91,10),end=seq(5,95,10),strand=1,col="black",ly=1,lwd=1,pch=1,cex=1,gene_type="blocks",fill="yellow")),
E=genoPlotR::as.dna_seg(data.frame(name=paste0("VERY.LONG.NAME.E.",1:10),start=seq(1,91,10),end=seq(5,95,10),strand=1,col="black",ly=1,lwd=1,pch=1,cex=1,gene_type="blocks",fill="orange")))
And a list of genoPlotR's annotation objects, which give coordinate information, also named according to the tree leaves:
annotation.list <- lapply(1:5,function(s){
mids <- genoPlotR::middle(dna.segs.list[[s]])
return(genoPlotR::annotation(x1=mids,x2=NA,text=dna.segs.list[[s]]$name,rot=30,col="black"))
})
names(annotation.list) <- names(dna.segs.list)
And the call to the function is:
genoPlotR::plot_gene_map(dna_segs=dna.segs.list,tree=tree,tree_width=2,annotations=annotation.list,annotation_height=1.3,annotation_cex=0.9,scale=F,dna_seg_scale=F)
Which gives:
As you can see the top and right box (gene) names get cut off.
I tried playing with pdf's width and height, when saving the figure to a file, and with the margins through par's mar, but they have no effect.
Any idea how to display this plot without getting the names cut off?
Currently genoPlotR's plot_gene_map does not have a legend option implemented. Any idea how can I add a legend, let's say which shows these colors in squares aside these labels:
data.frame(label = c("A","B","C","D","E"), color = c("red","blue","green","yellow","orange"))
Glad that you like genoPlotR.
There are no real elegant solution to your problem, but here are a few things you can attempt:
- increase annotation_height and reduce annotation_cex
- increase rotation (“rot”) in the annotation function
- use xlims to artificially increase the length of the dna_seg (but that’s a bad hack)
For the rest (including the legend), you’ll have to use grid and its viewports.
A blend of the first 3 solutions:
annotation.list <- lapply(1:5,function(s){
mids <- genoPlotR::middle(dna.segs.list[[s]])
return(genoPlotR::annotation(x1=mids, x2=NA, text=dna.segs.list[[s]]$name,rot=75,col="black"))
})
names(annotation.list) <- names(dna.segs.list)
genoPlotR::plot_gene_map(dna_segs=dna.segs.list,tree=tree,tree_width=2,annotations=annotation.list,annotation_height=5,annotation_cex=0.4,scale=F,dna_seg_scale=F, xlims=rep(list(c(0,110)),5))
For the better solution with grid: (note the "plot_new=FALSE" in the call to plot_gene_map)
# changing rot to 30
annotation.list <- lapply(1:5,function(s){
mids <- genoPlotR::middle(dna.segs.list[[s]])
return(genoPlotR::annotation(x1=mids,x2=NA,text=dna.segs.list[[s]]$name,rot=30,col="black"))
})
names(annotation.list) <- names(dna.segs.list)
# main viewport: two columns, relative widths 1 and 0.3
pushViewport(viewport(layout=grid.layout(1,2, widths=unit(c(1, 0.3), rep("null", 2))), name="overall_vp"))
# viewport with gene_map
pushViewport(viewport(layout.pos.col=1, name="geneMap"))
genoPlotR::plot_gene_map(dna_segs=dna.segs.list,tree=tree,tree_width=2,annotations=annotation.list,annotation_height=3,annotation_cex=0.5,scale=F,dna_seg_scale=F, plot_new=FALSE)
upViewport()
# another viewport for the margin/legend
pushViewport(viewport(layout.pos.col=2, name="legend"))
plotLegend(…)
upViewport()
Hope that helps!
Lionel
Which function or package could I use to add the legend? The R base functions did not seem to work for me. The following message is displayed:
Error in strheight(legend, units = "user", cex = cex) :
plot.new has not been called yet"

R figure being cropped

Here's a bit of a basic question, you'd think R would automate this always. I'm making a heatmap (basic stuff, png() into heatmap.2() into dev.off()), and my row labels get cleaved off on the right hand side, along with a tiny part of the dendrogram on the left:
Fiddling with the margins manually would eventually lead to a sensible output, but the problem is that this is part of an automated pipeline with biologist users in mind. Surely there's some automated way to do this, right? I mean, in RGui on OSX, a quick reshape of the figure window fixes the layout automatically, so it has to be possible. Thanks, and sorry to bother you.
EDIT: Procedure to reproduce this visualisation:
Input data:
Time,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48
CATMA1A23000,0.21129,0.48322,0.54234,0.93714,0.51816,0.11103,0.38304,0.97183,0.61381,-0.13775,0.32575,0.85221,0.1921,1.8692,0.4117,0.51977,0.74019,0.98932,0.023536,0.8849,0.75141,0.42846,0.03839,0.50295,0.38849,-0.95087,0.55017,-0.14813,0.79036,0.40978,-0.33048,0.81173,0.60585,0.014413,0.86586,0.063947,1.1195,0.25425,-0.090325,1.3035,0.90609,0.62866,0.83168,0.88655,0.4843,0.60098,0.26669,0.66605,0.78468,-0.76709,0.29615,-0.8911,0.5022,-0.93834,-0.065904,0.58003,0.41217,-0.99012,-0.032054,0.69119,1.1791,-0.0059458,0.81002,0.76421,1.302,0.77637,0.7824,1.192,-0.27005,-0.24698,1.8706,0.33513,0.38592,1.1987,0.48569,0.7104,2.4307,0.68148,0.11407,0.65619,0.94468,1.245,0.44146,0.71048,0.96389,1.7647,0.22729,0.96875,-0.2738,1.2975,2.0503,0.52507,2.282,1.0773,0.44489,0.22504
CATMA1A30870,3.9909,5.1844,5.2522,5.5482,5.665,5.4666,5.4456,5.5456,5.0014,5.5408,3.9324,3.9288,4.3624,3.0828,5.4821,5.1446,4.5638,4.6449,5.2604,4.2607,4.0942,3.9892,5.1361,3.8625,3.9454,5.3148,5.188,6.088,5.2085,5.3073,5.5652,4.8358,4.6111,4.9911,3.1497,4.3796,4.2456,3.9712,5.0998,5.4383,5.0908,4.5155,4.6486,5.1233,4.4259,4.7218,3.7928,4.0384,4.1085,6.2787,5.4937,5.9637,5.4085,5.188,5.3057,5.1963,4.3807,4.8352,3.9584,3.5859,3.8535,3.9755,4.5199,5.1093,5.3526,4.1214,4.5787,3.4499,4.1962,4.6929,4.3379,4.6376,4.4774,5.2341,5.3061,5.6769,3.6244,5.1073,4.543,4.9929,4.9341,3.9829,4.4304,4.0021,3.7498,4.2972,5.3338,4.8094,4.5766,5.5171,3.1207,5.0926,3.0253,4.351,4.351,4.5253
CATMA1A65800,0.65615,0.54186,0.93488,0.2205,0.38134,0.95061,0.60157,0.66508,0.83971,1.3625,0.9037,1.1606,1.0143,0.91896,1.3587,1.2468,1.0147,0.44113,1.5196,0.60232,0.52456,0.82557,0.43697,1.3253,0.78614,0.73697,1.0593,0.010271,0.59042,0.58544,0.38307,1.0372,1.071,0.21915,1.1779,0.97341,0.95672,0.92057,1.3866,1.3884,0.99241,1.0546,1.0215,1.0144,1.1606,1.2421,0.89549,0.56747,0.99347,1.0706,1.3403,0.48719,0.30759,1.0215,0.76474,0.87313,0.47597,1.5028,1.2201,1.7923,0.64299,1.3612,1.0079,0.64145,1.0969,0.90254,0.9109,0.85213,0.55241,0.63797,1.5373,0.45586,0.59624,0.5717,0.13919,-0.012128,2.7367,0.83577,0.13422,0.13908,0.32377,0.013345,-0.017209,0.47044,1.034,1.4932,1.0067,0.57515,1.1405,0.95364,3.0214,0.14601,2.1645,1.1704,0.45205,0.83406
CATMA1C71184,4.2879,2.7256,3.306,2.2375,2.6575,4.6438,4.3899,3.8518,5.3494,3.8049,5.4095,4.5437,3.4362,4.0983,2.5059,2.7275,3.9432,3.5177,4.266,4.6446,4.9338,3.5188,3.7903,4.4867,3.9692,3.3382,3.2898,3.4103,3.3025,4.1279,4.3532,5.0625,5.756,4.7799,5.0303,4.8974,3.8698,2.887,2.7541,2.7837,3.0665,4.0168,3.7507,4.6273,5.2384,3.7049,4.5843,3.97,2.7142,3.6205,3.5394,3.3561,3.2672,4.4467,5.2044,5.2177,3.8496,5.7881,4.7594,5.0395,2.8281,2.8751,2.8322,2.6873,1.8326,3.042,3.834,4.7844,3.1947,3.2571,4.0826,4.8398,3.8147,2.7439,2.846,2.64,2.8055,3.421,3.8495,4.9367,4.6413,3.5281,4.0636,3.7144,3.4468,2.3466,1.7452,2.3151,4.022,2.9211,3.89,3.7213,4.1856,3.3613,4.0891,4.2135
CATMA1C71776,-2.0266,-0.77692,-1.3279,-0.40422,-0.38614,-0.34387,-0.44277,0.99775,1.0748,0.17831,-0.14209,-0.98905,-0.88619,0.40548,-0.37731,0.18112,-0.80473,-0.26957,0.49049,0.25413,0.30341,0.20203,-1.0343,-0.17877,-0.46107,-1.202,-0.58841,-1.0995,-1.1079,-0.10977,0.29428,0.33363,0.35537,0.55571,-0.11074,-0.69584,-0.052035,-0.18207,-0.45321,-0.2778,-0.81074,-0.27129,0.087758,0.52214,0.33791,0.51601,-0.30863,0.14386,-0.2922,-0.21013,-0.73268,-1.1732,-0.36599,0.4731,1.0357,0.62377,0.8219,0.6029,-0.27195,1.0677,-0.48423,-0.57601,-0.43393,-2.0519,-0.67433,-0.44234,0.0078619,0.40677,-0.47102,-0.59971,0.30058,-0.4604,-0.56523,-3.3913,-0.52856,-0.54137,1.0418,-0.26115,0.21246,0.37858,0.38716,-0.86708,-0.41297,-0.21536,-0.06004,-0.48526,-1.2651,-0.52592,0.23757,-0.73376,1.0272,0.59383,0.65704,-0.017658,-0.44128,-0.30226
CATMA2A41800,1.5057,1.8357,2.7851,2.9125,2.6421,2.3881,2.4772,2.3367,2.2988,3.0073,2.7659,2.8454,2.5939,2.6327,2.6184,2.3415,3.3473,2.7683,1.1123,1.9614,1.8795,2.2335,2.9227,3.1536,2.6255,2.5264,2.3874,3.3196,1.8572,2.3446,2.3358,1.683,2.1742,2.8082,2.8634,2.8607,2.6755,3.2567,2.0726,3.0746,2.8984,2.5235,2.9399,2.5731,1.9196,2.9845,2.965,2.8055,1.1878,-0.6181,2.9552,2.7814,3.0701,-0.42372,2.5897,2.6331,1.7218,-0.70788,2.9578,1.1506,3.3772,1.6571,3.3166,3.5001,2.6541,2.5367,2.8643,2.1034,2.6389,1.8915,2.4861,3.2271,1.7718,2.7359,2.391,2.7223,1.1594,2.4025,1.1524,2.1405,2.253,2.4368,2.8053,2.2955,2.2877,2.7792,3.4115,3.2464,-0.37629,3.0582,1.682,2.0598,1.8747,2.0158,2.4714,2.1816
CATMA2C47274,2.2048,1.6574,0.96502,0.15092,0.5251,0.40351,0.90106,-0.12415,0.48846,0.03794,0.86292,0.27027,0.71848,1.8535,0.47188,-0.067504,0.68578,0.28113,0.17559,0.29659,0.067618,0.79368,-0.36732,0.80945,2.4297,1.3272,1.3741,0.005024,0.57369,0.6195,0.17845,1.3991,0.71594,-0.76358,0.74421,0.078431,0.97596,0.14151,-0.77085,0.64926,-0.24602,1.3478,0.49879,0.90549,0.78024,0.94685,0.023589,0.07446,1.3597,0.19311,1.1883,-0.20756,0.59042,0.031659,0.3591,1.1757,0.97314,-1.0133,0.92409,1.2264,-0.0095851,-0.47315,1.3107,1.3967,0.80332,0.5494,1.0394,1.4519,0.50253,-0.65282,1.5689,0.17996,1.5938,0.28124,0.93511,0.10344,3.6906,0.56448,-0.40754,0.75218,0.10346,-0.37737,-0.53789,0.57109,0.29602,-0.64821,-0.52805,0.34899,0.50146,0.61456,2.1785,-0.41,2.135,0.7426,0.3307,0.64542
CATMA2C47710,3.9021,3.7272,3.709,3.494,3.7557,3.7883,3.8697,3.4952,3.6365,3.6948,4.0954,3.7629,4.1282,3.6108,4.2769,3.3689,3.5232,3.7488,3.6237,4.0805,3.855,3.8724,4.2706,3.5584,3.9576,4.1324,3.857,3.6508,3.7609,3.7885,3.6256,3.8022,3.7189,3.7417,3.6357,3.6448,4.2841,3.8731,3.6047,3.7792,3.5703,3.8284,3.8098,3.8824,4.2441,3.6127,3.8253,3.529,3.6078,4.0917,3.6794,3.7977,3.8231,3.9369,3.6087,3.7634,3.6419,4.0052,3.7083,4.0191,3.3211,3.9133,3.74,4.0801,4.0999,3.6312,3.7747,3.7768,3.7977,3.9409,3.9423,3.6708,4.1773,3.666,3.8267,3.8832,4.0462,3.8007,3.3932,4.0945,3.9901,4.1036,4.1064,3.8178,3.7936,3.8638,4.3395,3.5859,3.5698,3.7885,4.4263,4.0292,3.6857,4.1197,4.0262,3.7753
CATMA3A13690,5.2022,5.6481,5.7765,4.8253,6.0581,6.2026,5.2711,6.4481,6.0929,6.3395,5.3806,4.9156,5.3634,4.5556,5.3547,5.5214,5.6947,5.9289,5.6269,5.5406,6.0508,5.8498,5.6275,5.4422,5.3293,5.7543,5.1577,6.3626,5.429,5.7245,5.7554,5.4575,5.2244,6.2312,6.0425,5.0317,5.4494,5.5252,5.5124,5.6588,5.0015,5.7454,5.6711,6.132,5.4789,6.1668,5.6978,5.113,4.3572,5.6177,5.9557,6.0099,5.2522,5.5598,6.2427,5.4703,5.4275,5.9159,5.3029,4.1094,5.927,5.9223,5.1257,5.3835,5.6579,5.5849,5.8674,4.9425,5.2144,5.5382,4.7165,5.5688,5.2766,6.4298,5.9438,5.7105,4.757,5.9097,5.3665,5.8336,5.8393,5.6104,5.4702,5.4028,5.0756,5.632,5.9963,5.7889,5.7521,5.5561,4.0685,6.3026,4.9628,6.176,5.7256,4.8529
CATMA3A15560,0.23073,0.32331,0.37953,0.081038,-0.33446,0.18495,0.86901,0.71363,0.33531,1.4741,0.32824,0.18869,-0.34772,0.97628,0.62455,-0.14645,0.42603,-0.00031328,0.92441,0.14199,0.25522,0.55583,0.10067,1.2818,0.64424,-0.24454,0.33039,0.25975,1.1023,-0.5464,0.62174,-0.15397,0.78478,0.2999,-0.063974,0.55156,0.44076,0.17798,0.61707,0.9308,0.19809,1.2378,0.26328,0.19767,0.069484,0.76748,0.45386,0.4495,0.050625,0.99311,-0.10988,-0.070507,0.46274,0.19475,0.36696,-0.16537,1.0566,0.94446,0.85272,1.194,-0.41335,0.17202,0.38729,0.65495,-0.32063,0.60186,0.24444,1.3128,0.48551,0.55998,1.8149,0.36494,0.10693,-0.19085,0.25082,-0.10628,-0.38432,0.50117,0.97923,-0.31536,-0.2634,-0.82767,0.70017,-0.0093473,0.27653,0.67773,0.40978,0.3315,0.5179,0.32044,2.9356,-0.51529,2.7438,0.4153,0.32022,0.74311
CATMA3A21390,-0.54603,-0.32262,-0.29966,-0.22463,-0.49654,-1.0552,-1.0705,-0.93928,-0.71247,-2.7228,-0.67849,-0.24868,-1.5015,-0.22486,-0.26215,-0.34298,-0.73168,-0.33699,-0.3455,-0.5349,-0.68784,-0.47506,-1.2541,0.86942,-0.14503,-2.0603,-0.35647,-0.67731,0.20243,-1.1881,-1.3828,-1.0471,-0.20157,-2.5492,-0.7862,-0.21715,-0.20583,-0.067758,-0.86589,-0.75509,-0.62777,-0.57176,-2.0996,-0.72894,-0.56391,-1.1054,-0.94172,-0.98805,-0.20763,-0.42764,-2.0142,-1.4079,-0.66326,-0.10354,-1.6284,-1.9413,-0.77001,-0.58492,-0.99846,-0.013285,-0.31205,-0.10665,-1.2396,-1.7556,-0.40454,-0.26631,-1.2694,-0.32263,-1.2293,-0.93683,0.97994,-1.8696,-0.26859,-0.25661,-0.33193,-0.83889,-0.25944,-0.63826,0.3387,-1.4443,-0.93123,-0.84915,-0.24606,-0.63109,-0.78621,-0.40802,-0.6463,-0.84319,-1.0379,-1.1471,1.9932,-1.3029,1.5286,-0.19754,0.018446,-0.55479
CATMA3A53880,3.917,3.6689,3.7213,3.8812,3.8253,4.4861,4.258,4.7926,4.9737,4.0869,3.2183,3.5812,3.408,3.3128,3.3915,4.1923,3.9122,4.0586,4.2707,4.3077,4.8926,4.1982,3.4817,3.5267,3.6952,3.6632,3.9304,4.0793,3.9499,4.2175,4.8303,4.9599,4.6336,3.8998,3.7932,3.8572,3.2167,3.7749,4.3971,4.0662,3.9241,4.6407,4.2837,4.9644,4.972,4.2565,3.8796,3.383,3.2382,4.1017,4.058,4.0423,3.6033,4.0774,5.141,4.9736,4.4372,3.8969,3.7386,3.3618,3.539,4.2588,3.4726,3.7424,3.5818,4.9159,4.3567,4.1291,4.1108,4.4035,3.1374,3.4675,3.762,3.9264,3.7319,4.1205,2.0915,4.4192,4.5049,4.5427,4.6205,3.4653,3.6017,3.3376,3.266,3.5561,3.4538,3.761,4.2013,4.1787,4.017,4.7773,3.748,4.4977,3.8685,3.7464
CATMA5A09500,6.2838,5.1076,6.6209,5.7153,5.9395,5.3601,4.2366,5.189,3.3074,4.8701,5.0357,5.0951,6.2843,5.691,5.5054,5.9949,5.0834,5.1484,4.5884,4.805,4.458,5.0816,4.7264,5.3661,5.0645,5.8293,5.2877,5.6602,5.3336,4.7329,4.843,5.1901,3.8431,4.683,5.7106,4.0774,6.5689,5.8061,5.3445,5.2905,3.837,4.6271,4.2277,4.6165,4.0081,4.5176,4.259,4.6363,4.8557,3.9828,5.9728,5.4698,5.4102,4.5802,5.0247,4.8967,4.0116,2.6636,5.4684,4.3454,6.6893,6.5624,6.1464,5.4444,5.3309,5.6682,5.5012,4.3162,2.9028,3.3906,4.6684,4.914,5.3601,5.5138,6.2191,5.8043,5.8165,5.1155,3.8681,4.9268,4.0232,6.1699,4.6327,5.7364,6.1934,6.7188,5.0755,5.7058,5.3703,4.3921,3.2108,4.9503,4.1003,4.8225,4.6701,4.7166
CATMA5A12680,1.7891,1.362,1.4303,0.61973,0.54124,1.2733,0.7775,0.66788,1.7338,0.63125,1.5852,0.91616,1.0712,0.81919,0.90152,0.77799,1.0835,0.32735,2.0868,0.5895,1.1445,0.64545,0.71776,0.33929,1.42,1.0729,1.4879,0.86379,0.95453,1.2928,0.97753,1.1738,0.79397,0.31563,0.86345,0.67595,1.3501,1.079,1.2034,1.2432,1.3696,1.1473,0.72528,0.57199,0.85965,0.65339,0.47614,0.43219,1.363,2.4026,0.98947,0.85204,1.2591,2.3151,1.6775,1.6555,1.0371,2.5586,-0.097071,0.91744,1.068,1.6819,1.0122,0.99911,0.75267,1.2195,0.42175,0.2554,0.4819,0.80025,0.44517,0.32442,1.9863,1.5019,1.2893,1.0669,1.6881,1.7581,1.6505,1.943,2.141,1.018,0.68207,0.84392,1.1452,1.009,1.1376,1.0572,1.9258,1.7039,0.10261,1.4549,0.94693,0.77945,0.049658,0.84178
CATMA5A14990,0.41247,0.51378,0.375,-0.24526,0.027658,-0.015345,-0.028278,-0.2643,0.3905,0.12299,0.94334,0.11482,0.50109,-0.55162,0.10768,-0.26433,-0.31064,-0.76526,1.0147,-0.73178,0.3323,-0.13657,-0.14013,-0.17878,0.31259,0.36723,0.55499,-0.2664,0.31862,0.60225,0.078919,0.18282,0.23014,-0.27835,0.16392,0.58131,1.052,0.062394,0.064929,-0.11918,-0.2167,-0.26018,-0.21649,-0.032523,-0.05763,-0.62775,-0.29148,0.13633,0.72715,1.535,0.08501,0.76137,0.54934,1.5163,-0.26612,0.58127,0.30339,1.8464,-0.17161,0.30309,-0.070279,0.28016,-0.036628,0.67464,0.34753,0.26499,-0.17856,-0.61162,-0.17941,-0.01017,0.21112,0.026389,0.64566,-0.39685,0.31403,-0.21637,1.1253,0.41434,0.77759,0.20421,0.70657,0.53273,-0.67276,-0.65656,0.6997,-0.06428,-0.13546,-0.15055,0.99804,1.4673,-0.47155,-0.056436,0.84609,-0.23068,-0.55114,0.68975
CATMA5A25890,-0.23072,0.82252,0.32512,0.13284,0.14406,0.005071,0.40953,-0.11252,-0.6367,-0.048073,0.21325,-0.046316,-0.35078,1.1023,-0.019882,-0.55825,-0.34621,0.1114,0.030302,-0.08142,0.19157,0.5152,-0.034952,0.20984,1.0547,0.4816,0.31078,0.14731,0.31811,-0.27275,-0.47217,-0.043207,0.29109,0.41192,-1.069,0.23357,-0.17453,0.015661,-0.26869,0.14587,0.19336,0.5926,-0.1583,0.61242,0.18635,0.01207,-0.21772,0.13986,1.9305,0.3349,0.62954,-0.04455,1.121,-0.14155,-0.33772,-0.42633,0.41828,-0.29794,-0.7107,1.4786,-0.37442,-0.45371,0.16175,-0.057764,-0.11803,-0.037838,0.25868,0.88605,0.33225,-0.24331,0.93084,-0.33266,0.9762,0.24755,0.30857,0.14661,1.8351,0.40313,0.45084,-0.52105,-0.31271,-0.37122,-0.28615,-0.0023692,-0.43072,-0.24417,-0.5184,0.13874,-0.32606,-0.1705,2.1396,-0.77657,2.3056,0.32096,0.29337,-0.034746
CATMA5A31940,4.4307,4.8735,4.7911,5.8201,5.9587,5.576,5.9084,5.849,5.2832,5.5423,5.0275,4.5254,4.5054,3.0696,5.6512,4.3986,4.9856,4.9222,4.951,4.5506,4.2185,4.3184,5.4783,4.4515,3.9397,5.6269,5.0988,6.1254,5.7446,5.6146,5.452,5.2047,5.3527,5.93,4.8931,5.5529,3.9876,4.1072,4.0583,5.4324,5.4681,4.392,4.5189,5.0629,4.9347,5.2165,4.6681,4.7428,4.1539,6.3376,5.353,6.2896,5.5844,5.1654,5.4391,5.3933,5.261,5.6974,4.5142,3.9851,3.569,4.0946,4.6662,5.1085,5.0319,4.4598,4.8672,3.7326,5.3032,5.0448,4.7771,4.2209,4.1886,4.284,5.4681,5.8331,4.7683,5.6614,5.3313,5.2017,5.1002,5.0642,4.4867,4.8576,4.1454,4.0971,5.0368,4.845,4.753,5.5496,2.9838,5.1394,3.342,4.1246,5.0121,4.618
Code proper (BHC is from Bioconductor):
library(argparse)
library(RColorBrewer)
library(BHC)
library(parallel)
library(gplots)
#data prep and clustering, to get dendrograms etc as shown in plot
data = read.csv('input.csv',header=TRUE,row.names=1,check.names=FALSE)
genes = rownames(data)
samples = colnames(data)
data = data.matrix(data)
standardisedData = (data-mean(data))/sd(data)
samples = as.numeric(samples)
hc = bhc(standardisedData, genes, timePoints=samples, dataType='time-course', verbose=TRUE)
#the plotting proper
png('heatmap.png',width=6,height=6,units='in',res=300)
heatmap.2(standardisedData, Colv=NA, Rowv=hc, tracecol=NA, scale="none", col=brewer.pal(11,'RdBu'))
#heatmap.2(standardisedData, Colv=NA, Rowv=hc, tracecol=NA, scale="none", col=brewer.pal(11,'RdBu'), margins=c(3,10)) <- this fixes it on a single-case basis
dev.off()
I would suggest just giving it a fairly wide default margin, such that it should be clipped even with longer labels, e.g.:
heatmap.2(standardisedData, Colv=NA, Rowv=hc, tracecol=NA, scale="none", col=brewer.pal(11,'RdBu'), margins=c(14, 14))
The default margin size is (5,5). The above increases the both the column and row margins, but you can increase just one or the other as well.
If you want to be more precise, you could try using max(strwidth(rownames(standardisedData))) to determine the amount of space needed by the largest label, and then convert that into the units expected by par(mar=*) (what heatmap.2() uses to specify plot margins.)
I think this should do the trick:
# determine margins to use
png('/tmp/trash', width=6,height=6,units='in',res=300)
plot.new()
margin_width = max(strwidth(rownames(standardisedData), units='inches')) * par('fin')[1]
dev.off()
#the plotting proper
png('heatmap.png',width=6,height=6,units='in',res=300)
heatmap.2(standardisedData, Colv=NA, Rowv=hc, tracecol=NA, scale="none", col=brewer.pal(11,'RdBu'), margins=c(5, margin_width))
dev.off()

Using grconvertX/grconvertY in ggplot2

I am trying to figure out how to use grconvertX/grconvertX in ggplot. My ultimate goal is to to add annotation to a ggplot2 figure (and possibly lattice) with grid.text and grid.lines by going from user coordinates to device coordinates. I know it can be done with grobs but I am wondering if there is an easier way.
The following code allows me to pass values from user coordinates to ndc coordinates and use those values to annotate the plot with grid.text.
graphics.off() # close graphics windows
library(grid)
library(gridBase)
test= data.frame(
x = c(1,2,3),
y = c(12,10,3),
n = c(75,76,73)
)
par(mar = c(13,5,2,3))
plot(test$y ~ test$x,type="b", ann=F)
for (i in 1:nrow(test))
{
X=grconvertX(i , from="user", to="ndc")
grid.text(x=X, y =0.2, label=paste("GRID.text at\nuser.x=", i, "\n", "ndc.x=", (signif( X, 5)) ) )
grid.lines(x=c(X, X), y = c(0.28, 0.33) )
}
#add some code to save as PDF ...
The code is based on the solution from one of my previous posts: Mixing X and Y coordinate systems . You can see how x coordinates from the original plot were converted to ndc. The advantage of this approach is that I can use device coordinates for Y.
I assumed I could easily do the same in ggplot2 (and possibly in lattice).
library(ggplot2)
graphics.off() # close graphics windows
qplot(x=x, y=y, data=test)+geom_line()+ opts(plot.margin = unit(c(1,3,8,1), "lines"))
for (i in 1:nrow(test))
{
X=grconvertX(i , from="user", to="ndc")
grid.text(x=X, y =0.2, label=paste("GRID.text at\nuser.x=", i, "\n", "ndc.x=", (signif( X, 5)) ) )
grid.lines(x=c(X, X), y = c(0.28, 0.33) )
}
#add some code to save as PDF...
However, it does not work correctly. The coordinates seem to be a bit off. The vertical lines and text don't correspond to the tick labels on the plot. Can anybody tell me how to fix it? Thanks a lot in advance.
The grconvertX and grconvertY functions work with base graphics while ggplot2 uses grid graphics. In general the 2 different graphics engines don't play nicely together (though you have demonstrated using gridBase to help). Your first example works because you started with a base graphic so the user coordinate system exists with the base graph and grconvertX converts from it. In the second case the user coordinate system was never set in the base graphics, so it looks like it might use the default coordinates of 0,1 which are similar but not identical to the top viewport coordinates so you get something similar but not exactly correct (I am actually surprised that you did not get an error or warning
Generally for grid graphics the equivalent for converting between coordinates is to just create a new viewport with the coordinate system of interest (or push/pop to an existing viewport with the correct coordinate system), then add your annotations in that viewport.
Here is an example that creates your plot, then moves down to the viewport containing the main plot, creates a new viewport with the same dimensions but with clipping turned off, the x scale is based on the data and the y scale is 0,1, then adds some text accordingly:
library(ggplot2)
library(grid)
test= data.frame( x = c(1,2,3), y = c(12,10,3), n = c(75,76,73) )
qplot(x=x, y=y, data=test)+geom_line()+ opts(plot.margin = unit(c(1,3,8,1), "lines"))
current.vpTree()
downViewport('panel-3-4')
pushViewport(dataViewport( test$x, clip='off',yscale=c(0,1)))
for (i in 1:nrow(test)) {
grid.text(x=i, y = -0.2, default.units='native',
label=paste("GRID.text at\nuser.x=", i, "\n" ) )
grid.lines(x=c(i, i), y = c(-0.1, 0), default.units='native' )
}
One of the tricky things here is that ggplot2 does not set the viewport scales to match the data being plotted, but does the conversions itself. In this case setting the scale based on the x data worked, but if ggplot2 does something fancier then this might not work. What we would need is some way to get the back tranformed coordinates from ggplot2 to use in the call to grid.text.

lattice or latticeExtra combine multiple plots different yscaling (log10 and non-transformed)

I have a multiple variable time series were some of the variables have rather large ranges. I wish to make a single-page plot with multiple stacked plots of each variable were some of the variables have a log10 y-axis scaling. I am relatively new to lattice and have not been able to figure out how to effectively mix the log10 scaling with non-transformed axes and get a publication quality plot. If print.trellis is used the plots are not aligned and the padding needs some work, if c.trellis is used the layout is good, but only the y-scaling from only one plot is used. Any suggestions for an efficient solution, where I can replicate the output of c.trellis using the different y-scaling for each (original) object?
Example below:
require(lattice)
require(latticeExtra)
# make data.frame
d.date <- as.POSIXct(c("2009-12-15", "2010-01-15", "2010-02-15", "2010-03-15", "2010-04-15"))
CO2dat <- c(100,200,1000,9000,2000)
pHdat <- c(10,9,7,6,7)
tmp <- data.frame(date=d.date ,CO2dat=CO2dat ,pHdat=pHdat)
# make plots
plot1 <- xyplot(pHdat ~ date, data=tmp
, ylim=c(5,11)
, ylab="pHdat"
, xlab="Date"
, origin = 0, border = 0
, scales=list(y=list(alternating=1))
, panel = function(...){
panel.xyarea(...)
panel.xyplot(...)
}
)
# make plot with log y scale
plot2 <- xyplot(CO2dat ~ date, data=tmp
, ylim=c(10,10^4)
, ylab="CO2dat"
, xlab="Date"
, origin = 0, border = 0
, scales=list(y=list(alternating=1,log=10))
, yscale.components = yscale.components.log10ticks
, panel = function(...){
panel.xyarea(...)
panel.xyplot(...)
# plot CO2air uatm
panel.abline(h=log10(390),col="blue",type="l",...)
}
)
# plot individual figures using split
print(plot2, split=c(1,1,1,2), more=TRUE)
print(plot1, split=c(1,2,1,2), more=F)
# combine plots (more convenient)
comb <- c(plot1, plot2, x.same=F, y.same=F, layout = c(1, 2))
# plot combined figure
update(comb, ylab = c("pHdat","log10 CO2dat"))
Using #joran's idea, I can get the axes to be closer but not exact; also, reducing padding gets them closer together but changes the aspect ratio. In the picture below I've reduced the padding perhaps by too much to show the not exactness; if this close were desired, you'd clearly want to remove the x-axis labels on the top as well.
I looked into the code that sets up the layout and the margin on the left side is calculated from the width of the labels, so #joran's idea is probably the only thing that will work based on the printing using split, unless one were to rewrite the plot.trellis command. Perhaps the c method could work but I haven't found a way yet to set the scale components separately depending on the panel. That does seem more promising though.
mtheme <- standard.theme("pdf")
mtheme$layout.heights$bottom.padding <- -10
plot1b <- update(plot1, scales=list(y=list(alternating=1, at=5:10, labels=paste(" ",c(5:10)))))
plot2b <- update(plot2, par.settings=mtheme)
pdf(file="temp.pdf")
print(plot2b, split=c(1,1,1,2), more=TRUE)
print(plot1b, split=c(1,2,1,2), more=F)

Resources