0

I am working on this question here to get a legend from a subplot of 2x2 plots to its whole window. The goal is to get a single legend and then remove the other legends, only one legend is enough and that should be positioned on the right of the whole pane.

enter image description here

Perhaps relevant

  1. Global legend using grid.arrange (gridExtra) and lattice based plots

Code

require(lattice)
require(gridExtra)

f<-function(x) as.double(as.character(x))   #factors converted to vectors https://stackoverflow.com/a/40680020/54964

data.female <- structure(list(N11.1 = structure(c(3L, 3L), .Label = c("", "0.0", 
"1.0", "N11"), class = "factor"), N22.1 = structure(c(2L, 2L), .Label = c("", 
"0.0", "2.0", "N22"), class = "factor"), N33.1 = structure(c(2L, 
2L), .Label = c("", "0.0", "N33"), class = "factor"), N44.1 = structure(2:3, .Label = c("", 
"0.0", "0.1", "0.2", "N44"), class = "factor"), N21.1 = structure(c(2L, 
2L), .Label = c("", "0.0", "N21"), class = "factor"), N31.1 = structure(c(2L, 
2L), .Label = c("", "0.0", "N31"), class = "factor"), N32.1 = structure(c(5L, 
7L), .Label = c("", "0.0", "10.8", "11.0", "12.0", "17.0", "20.9", 
"22.8", "24.0", "3.0", "4.0", "44.0", "N32"), class = "factor")), .Names = c("N11.1", 
"N22.1", "N33.1", "N44.1", "N21.1", "N31.1", "N32.1"), row.names = c("Sinus", 
"Arr/AHB"), class = "data.frame")

data.male <- structure(list(N11.1 = structure(c(3L, 3L), .Label = c("", "0.0", 
"1.0", "N11"), class = "factor"), N22.1 = structure(c(2L, 2L), .Label = c("", 
"0.0", "2.0", "N22"), class = "factor"), N33.1 = structure(c(2L, 
2L), .Label = c("", "0.0", "N33"), class = "factor"), N44.1 = structure(c(2L, 
2L), .Label = c("", "0.0", "0.1", "0.2", "N44"), class = "factor"), 
    N21.1 = structure(c(2L, 2L), .Label = c("", "0.0", "N21"), class = "factor"), 
    N31.1 = structure(c(2L, 2L), .Label = c("", "0.0", "N31"), class = "factor"), 
    N32.1 = structure(c(11L, 9L), .Label = c("", "0.0", "10.8", 
    "11.0", "12.0", "17.0", "20.9", "22.8", "24.0", "3.0", "4.0", 
    "44.0", "N32"), class = "factor")), .Names = c("N11.1", "N22.1", 
"N33.1", "N44.1", "N21.1", "N31.1", "N32.1"), row.names = c("Sinus", 
"Arr/AHB"), class = "data.frame")

ID<-c("Sinus","Arr/AHB")

tl <- "female"
p1 <- barchart(f(N11.1)+f(N22.1)+f(N33.1)+f(N44.1)+f(N21.1)+f(N31.1)+f(N32.1) ~ ID,
         data=data.female,
         auto.key=list(space='right'), 
         ylim=c(0,50),
     beside=TRUE,
     ylab = "Number of cases", 
     xlab = "Population/Sample",
     main = tl
         )
tl <- "male"
p2 <- barchart(f(N11.1)+f(N22.1)+f(N33.1)+f(N44.1)+f(N21.1)+f(N31.1)+f(N32.1) ~ ID,
         data=data.male,
         auto.key=list(space='right'),
         ylim=c(0,50),
     beside=TRUE,
     ylab = "Number of cases", 
     xlab = "Population/Sample",
     main = tl 
         )

# Just repeat two barcharts more to get 2x2 example
tl <- "female"
p3 <- barchart(f(N11.1)+f(N22.1)+f(N33.1)+f(N44.1)+f(N21.1)+f(N31.1)+f(N32.1) ~ ID,
         data=data.female,
         auto.key=list(space='right'), 
         ylim=c(0,50),
     beside=TRUE,
     ylab = "Number of cases", 
     xlab = "Population/Sample",
     main = tl
         )
tl <- "male"
p4 <- barchart(f(N11.1)+f(N22.1)+f(N33.1)+f(N44.1)+f(N21.1)+f(N31.1)+f(N32.1) ~ ID,
         data=data.male,
         auto.key=list(space='right'),
         ylim=c(0,50),
     beside=TRUE,
     ylab = "Number of cases", 
     xlab = "Population/Sample",
     main = tl)



grid.arrange(p1,p2,p3,p4, ncol=2, nrow=2,left=("LEFT TITLE"),right=("RIGHT"),bottom=("BOTTOM"), top=("TOP"))

that compiles producing the above grid plots but the following does not work because of the legend

grid.arrange(p1,p2,p3,p4, ncol=2, nrow=2,
        legend=list(space='right',
        text=c("N11.1","N22.1","N33.1","N44.1","N21.1","N31.1","N32.1"),
                    columns=1))

where the easiest way would be to inherit the legend from some of the subplots and use something like auto.key but I could not get such commond working so trying to create the grop object with legend command.

What is wrong in the legend command and is there any convient way to inherit the legend of the subplots to the whole pane so auto.key could be used in the exterior of the pane?

Helper questions

  1. How does the colours get inherited from the automatic glob creation command auto.key to the legend?

  2. Instead of manually writing the legend labels (N11.1,N22.1,...), how can you conveniently get it from a subplot?

Community
  • 1
  • 1
hhh
  • 50,788
  • 62
  • 179
  • 282
  • 1
    lattice doesn't really allow creating a grob without drawing it, so it's a little difficult to extract a legend from a plot before drawing it on a device. – baptiste Nov 20 '16 at 01:50
  • @baptiste which way do you recommend to overcome this? – hhh Nov 20 '16 at 08:53
  • 1
    personally i'd use facetting and/or ggplot2. But with lattice i'd probably look at setting up things with low-level grid functions, navigating viewports after drawing, extracting one legend as grob, re-drawing it in a new viewport, etc. Painful but probably doable. Or for a one-off I'd probably use Illustrator to edit my plot manually. – baptiste Nov 20 '16 at 09:09

1 Answers1

0

I posted an answer here. The idea is to avoid inserting the key within the plot and use draw.key() to print a defined key anywhere on the final grid.arranged plot.