I wish to create a horizontal legend with multiple rows using base R (not ggplot). There is an option for multiple columns but not multiple rows in legend(). Is there a way to do this? Example to play with below where the horizontal legend it too wide for the plot.
MyCol <- topo.colors(20)
barplot(rep(1,20), yaxt="n", col=MyCol)
x <- 1:20
MyLab <- paste("Zone",x)
legend("bottom",MyLab,fill=MyCol,horiz=T)
You can use the ncol =
parameter instead of horiz
to get the layout you want. Note that horiz
overrides ncol
, so don't use both together. Although, this does not specify the number of rows directly, it does do so indirectly, because the number of rows is determined by the number of columns and factors.
MyCol <- topo.colors(20)
barplot(rep(1,20), yaxt="n", col=MyCol)
x <- 1:20
MyLab <- paste("Zone",x)
legend("bottom",MyLab,fill=MyCol,ncol=5)
If you want to arrange the legend items ordered along rows, you can do this by indexing them in the order you want. E.g.
MyOrder = matrix(1:20, nrow = 4, ncol = 5, byrow = T)
legend("bottom",MyLab[MyOrder], fill=MyCol[MyOrder] ,ncol=5)
To generalize for different numbers of rows and factors, we can do something like
Nfact = 21
Nrows = 5
Ncols = ceiling(Nfact / Nrows)
MyOrder = matrix(1:(Nrows*Ncols), nrow=Nrows, ncol=Ncols, byrow=T)
MyCol <- topo.colors(Nfact)
x <- 1:Nfact
MyLab <- paste("Zone",x)
barplot(rep(1,Nfact), yaxt="n", col=MyCol)
legend("bottom", MyLab[MyOrder], fill = MyCol[MyOrder], ncol = Ncols, border=NA)
And a final extra trick: In the previous plot, we set border=NA. This is to prevent borders being drawn around empty legend items (those at the bottoms of incomplete columns). If you want borders, then we should also create a vector of border colours that is NA
only in the locations we don't want to draw.
MyBorders = rep("black", Nrows*Ncols)
MyBorders[MyOrder > Nfact] <- NA
legend("bottom", MyLab[MyOrder], fill = MyCol[MyOrder], ncol = Ncols, border=MyBorders)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With