Re: [R] How to get legend outside of plot?
Hi, I think this is a very common question on this list. I've just created a page in the R wiki (inspired by https://stat.ethz.ch/pipermail/r-help/2007-May/132466.html) . With some suggestions and improvements, hopefully we can make a good reference for others to refer to in the future: http://wiki.r-project.org/rwiki/doku.php?id=tips:graphics-misc:legendoutside Hope this helps, baptiste On 14 Jan 2009, at 01:27, Mike Williamson wrote: I am creating a CDF plot function more user-friendly than any default r function. Depending upon the bimodality of the data (it is often bimodal), or any other strange data trends, the points can end up gathering in just about any corner of the plot. So, when I add a legend, whether I choose to add it in the bottom right, top left, or wherever, it will sometimes end up putting the legend right on the data itself. So, I tried to force the legend to certain data values (e.g., the largest in x the smallest in y, to really get the bottom right), but then this means most of the legend is missing because it is outside of the plot region. How can I create a legend that is fully outside of the plot, similar to what excel does by default, for example? Thanks! Mike [[alternative HTML version deleted]] __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. _ Baptiste AuguiƩ School of Physics University of Exeter Stocker Road, Exeter, Devon, EX4 4QL, UK Phone: +44 1392 264187 http://newton.ex.ac.uk/research/emag __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] How to get legend outside of plot?
Dear Mike: 1. Might it work to use legend(x = if(median(data) mean(range(data))) topleft, else bottomright, ...)? 2. The first two hits to 'RSiteSearch(points outside plot region)' suggested setting par(xpd=TRUE), then specifying x and y in legend appropriately outside the plot region. For example, par(mar=c(5, 4, 4, 11)+0.1, xpd=TRUE) would leave room on the left hand side of the plot. Then legend(max(x), max(y), ...) would put the legend top right outside the plot. The following is a modification of the first example from the legend help page: leg.txt - c(Setosa Petals, Setosa Sepals, Versicolor Petals, Versicolor Sepals) op - par(mar=c(5, 4, 4, 11)+.1, xpd=TRUE) legend(0, -1, leg.txt) matplot(c(1,8), c(0,4.5), type = n, xlab = Length, ylab = Width, main = Petal and Sepal Dimensions in Iris Blossoms) legend(9, 4.5, leg.txt, pch = sSvV, col = c(1, 3)) par(op) 3. The lattice package offers more control for this kind of thing. This package is quite valuable for multivariate displays of all kinds. Unfortunately, I found it difficult to learn. For me an essential reference is Sarkar (2008) Lattice: Multivariate Data Visualization with R (Springer). Hope this helps. Un fuerte abrazo, Spencer Mike Williamson wrote: I am creating a CDF plot function more user-friendly than any default r function. Depending upon the bimodality of the data (it is often bimodal), or any other strange data trends, the points can end up gathering in just about any corner of the plot. So, when I add a legend, whether I choose to add it in the bottom right, top left, or wherever, it will sometimes end up putting the legend right on the data itself. So, I tried to force the legend to certain data values (e.g., the largest in x the smallest in y, to really get the bottom right), but then this means most of the legend is missing because it is outside of the plot region. How can I create a legend that is fully outside of the plot, similar to what excel does by default, for example? Thanks! Mike [[alternative HTML version deleted]] __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] How to get legend outside of plot?
How can I create a legend that is fully outside of the plot, similar to what excel does by default, for example? The common solution with traditional plots (pre-modifying the margin) works well for a one-shot plot, where you calculate the legend size by trial-and-error. The problem arises when you need to automate this process for different legend texts/sizes. The best solution in this case is to use lattice or ggplot, as others have pointed. If still you want to stick to traditional plots, I have developed the functions below that may help. The idea is to estimate the legend size in an absolute measure unit like inches prior to plotting. This code is preliminary and not very well tested, so you may need to modify it. The legend size estimation algorithm is very simple, it can be improved by matching what the legend() function really works, but it works well with most of my plots. A basic drawback is that the legend is not redrawn correctly when the plot window is resized Run this example client code to see how it works: x - 0:64/64; legendText - paste(sin(, 1:5, pi * x)); oldPar - par(ask=FALSE, mai=c(1.02, 0.82, 0.82, 0.42)); for (location in c(outright, outbottom, outleft, outtop)) { if (!identical(location, outright)) par(ask=TRUE, mai=c(1.02, 0.82, 0.82, 0.42)); estimate.legend.size(location, legendText, col=1:5, lty=1:5, pch=*, cex=0.8); matplot(x, outer(x, 1:5, function(x, k) sin(k * pi * x)), type=o, col=1:5, ylim= c(-1, 1.5), pch=*, main=TITLE); legend(0, 1.5, legendText, col=1:5, lty=1:5, pch=*, ncol=3, cex=0.8); place.legend(location, legendText, col=1:5, lty=1:5, pch=*, cex=0.8); } par(oldPar); Suggestions for improvement welcomed! Best, Enrique # #' Converts distances between margin units. Possible units are inches, columns of text, or user coordinates. #' #' @param width numeric with the distance width in the \code{input} units. #' @param height numeric with the distance height in the \code{input} units. #' @param input string with the input units. The valid values are \code{inches}, \code{mlines} (margin lines), #' and \code{user} (user plot coordinates). #' #' @returns A list with elements \code{inches}, \code{mlines}, and \code{user}, each of which is a list with #' elements \code{width} and \code{height}. #' #' @seealso \link{\codegrconvertX}}, \link{\codegrconvertY}}. cnvrt.plot.distance - function(width=NA, height=NA, input=c(inches, mlines, user)) { n - max(length(width), length(height)); width - rep(as.numeric(width), length.out=n); height - rep(as.numeric(height), length.out=n); input - match.arg(input); cusr - par('usr'); # Extremes c(x1, x2, y1, y2) of the user coordinates of the plotting region. cpin - par('pin'); # The current plot dimensions (width, height), in inches. ccin - par('cin'); # Character size (width, height) in inches. cmex - par('mex'); # A character size expansion factor which is used to describe coordinates in the # margins of plots. Note that this does not change the font size, rather specifies # the size of font (as a multiple of csi) used to convert between mar and mai, and between oma and omi. if (input == inches) { inches - list(width = width , height = height); user - list(width = width / cpin[1] * (cusr[2] - cusr[1]), height = height / cpin[2] * (cusr[4] - cusr[3])); mlines - list(width = width / ccin[2] / cmex, height = height / ccin[2] / cmex ); } else if (input == mlines) { mlines - list(width = width , height = height); inches - list(width = width * ccin[2] * cmex, height = height * ccin[2] * cmex ); user - list(width = inches$width / cpin[1] * (cusr[2] - cusr[1]), height = inches$height / cpin[2] * (cusr[4] - cusr[3])); } else if (input == user) { user - list(width = width , height = height); inches - list(width = width * cpin[1] / (cusr[2] - cusr[1]), height = height * cpin[2] / (cusr[4] - cusr[3])); mlines - list(width = inches$width / ccin[2] / cmex, height = inches$height / ccin[2] / cmex ); } list(inches=inches, mlines=mlines, user=user); } # #' Modifies plot margins. #' #' @param side a number in 1:4 or a string specifying the margin side to modify.
[R] How to get legend outside of plot?
I am creating a CDF plot function more user-friendly than any default r function. Depending upon the bimodality of the data (it is often bimodal), or any other strange data trends, the points can end up gathering in just about any corner of the plot. So, when I add a legend, whether I choose to add it in the bottom right, top left, or wherever, it will sometimes end up putting the legend right on the data itself. So, I tried to force the legend to certain data values (e.g., the largest in x the smallest in y, to really get the bottom right), but then this means most of the legend is missing because it is outside of the plot region. How can I create a legend that is fully outside of the plot, similar to what excel does by default, for example? Thanks! Mike [[alternative HTML version deleted]] __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] How to get legend outside of plot?
I also have this problem! I would be great to hear a solution. Mike Williamson-9 wrote: I am creating a CDF plot function more user-friendly than any default r function. Depending upon the bimodality of the data (it is often bimodal), or any other strange data trends, the points can end up gathering in just about any corner of the plot. So, when I add a legend, whether I choose to add it in the bottom right, top left, or wherever, it will sometimes end up putting the legend right on the data itself. So, I tried to force the legend to certain data values (e.g., the largest in x the smallest in y, to really get the bottom right), but then this means most of the legend is missing because it is outside of the plot region. How can I create a legend that is fully outside of the plot, similar to what excel does by default, for example? Thanks! Mike [[alternative HTML version deleted]] __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. -- View this message in context: http://www.nabble.com/How-to-get-legend-outside-of-plot--tp21448346p21449657.html Sent from the R help mailing list archive at Nabble.com. __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.