Hello r-users I want to plot some barplots inside a looping with the legend placed outside the plotting area. No matter the number of bars I want the legend to be placed centered on the x-axis. See the example below for(i in 1:10) { var_1 <- sample(1000:100000,sample(3:8,1)) ymax <- max(var_1) b<-barplot(var_1,col="blue") var_2 <- sample(1000:ymax,length(var_1)) lines(rowSums(b),var_2,type="o",col="red",pch=16) par(xpd=TRUE) legend(*1.1* ,ymax*-0.072,c("var_1","var_2"),horiz=T,cex=1.3,bty="n",pch=c(15,16),col=c("blue","red"),lty=c(0,1),lwd=c(0,2),pt.cex=2) readline(prompt="Press [enter] to continue") } What I should use as x position in legend(x,y, ...), instead of *1.1*, to have the legend centered on the x-axis? I would love to use something like legend(x="center",y=ymax*-0.072, ... but it did not worked. I appreciate any suggestions. Best regards. Antonio [[alternative HTML version deleted]]
> On May 11, 2017, at 1:36 PM, Antonio Silva <aolinto.lst at gmail.com> wrote: > > Hello r-users > > I want to plot some barplots inside a looping with the legend placed > outside the plotting area. > > No matter the number of bars I want the legend to be placed centered on the > x-axis. > > See the example below > > for(i in 1:10) { > var_1 <- sample(1000:100000,sample(3:8,1)) > ymax <- max(var_1) > b<-barplot(var_1,col="blue") > var_2 <- sample(1000:ymax,length(var_1)) > lines(rowSums(b),var_2,type="o",col="red",pch=16) > par(xpd=TRUE) > legend(*1.1* > ,ymax*-0.072,c("var_1","var_2"),horiz=T,cex=1.3,bty="n",pch=c(15,16),col=c("blue","red"),lty=c(0,1),lwd=c(0,2),pt.cex=2) > readline(prompt="Press [enter] to continue") > } > > What I should use as x position in legend(x,y, ...), instead of *1.1*, to > have the legend centered on the x-axis? > > I would love to use something like legend(x="center",y=ymax*-0.072, ... but > it did not worked.co > > I appreciate any suggestions. Best regards. > > AntonioHi, There is a level of magic that goes into the legend() code to determine the placement of the legend. You can take the time to review the code for the function, noting how, internally, the location of the box that contains the legend is determined. Somebody may have an easier way to do this, but one approach is to first call legend() but set 'plot = FALSE' and obtain the return values of the function for use in a second call that will draw the legend in the position you desire. Here is some basic information: # Draw the initial barplot barplot(1:5) # Call legend() the first time, but don't draw it # See ?legend for the Value section # Use "bottom" to get the legend drawn in the center of the x axis, but it # will be within the plot region by default. # Just save the 'rect' component of the returned value BOX <- legend("bottom", legend = c("Label 1", "Label 2"), plot = FALSE)$rect # This gives us the width and height of the box containing the legend # as well as the x,y coordinates of the upper left hand corner> BOX$w [1] 1.002451 $h [1] 0.5872093 $left [1] 2.598775 $top [1] 0.5372093 Now, using BOX$left, which defines the x axis value for the left side of the legend box that is centered, we can call legend() a second time and adjust the y axis value of the legend to place it outside the plot region, below the plot. Just be sure that your second call to legend() is exactly the same as the first call, other than setting legend to FALSE in the first case. Any change in legend content between the two calls will alter the size and position of the enclosing box. par(xpd = TRUE) legend(BOX$left, y = -0.25, legend = c("Label 1", "Label 2")) You can then adapt that basic approach to use in your code. As an FYI, see ?par and note "usr", which defines the coordinates of the plot region. If desired, you can get the midpoint of the x axis using: mean(par("usr")[1:2]) Regards, Marc Schwartz
Thanks for you attention Mark. Your approach is really very interesting. I will try to apply it in my code. All the best Antonio 2017-05-11 16:19 GMT-03:00 Marc Schwartz <marc_schwartz at me.com>:> > > On May 11, 2017, at 1:36 PM, Antonio Silva <aolinto.lst at gmail.com> > wrote: > > > > Hello r-users > > > > I want to plot some barplots inside a looping with the legend placed > > outside the plotting area. > > > > No matter the number of bars I want the legend to be placed centered on > the > > x-axis. > > > > See the example below > > > > for(i in 1:10) { > > var_1 <- sample(1000:100000,sample(3:8,1)) > > ymax <- max(var_1) > > b<-barplot(var_1,col="blue") > > var_2 <- sample(1000:ymax,length(var_1)) > > lines(rowSums(b),var_2,type="o",col="red",pch=16) > > par(xpd=TRUE) > > legend(*1.1* > > ,ymax*-0.072,c("var_1","var_2"),horiz=T,cex=1.3,bty="n",pch> c(15,16),col=c("blue","red"),lty=c(0,1),lwd=c(0,2),pt.cex=2) > > readline(prompt="Press [enter] to continue") > > } > > > > What I should use as x position in legend(x,y, ...), instead of *1.1*, to > > have the legend centered on the x-axis? > > > > I would love to use something like legend(x="center",y=ymax*-0.072, ... > but > > it did not worked.co > > > > I appreciate any suggestions. Best regards. > > > > Antonio > > > Hi, > > There is a level of magic that goes into the legend() code to determine > the placement of the legend. You can take the time to review the code for > the function, noting how, internally, the location of the box that contains > the legend is determined. > > Somebody may have an easier way to do this, but one approach is to first > call legend() but set 'plot = FALSE' and obtain the return values of the > function for use in a second call that will draw the legend in the position > you desire. > > > Here is some basic information: > > # Draw the initial barplot > barplot(1:5) > > # Call legend() the first time, but don't draw it > # See ?legend for the Value section > # Use "bottom" to get the legend drawn in the center of the x axis, but it > # will be within the plot region by default. > # Just save the 'rect' component of the returned value > BOX <- legend("bottom", legend = c("Label 1", "Label 2"), plot > FALSE)$rect > > # This gives us the width and height of the box containing the legend > # as well as the x,y coordinates of the upper left hand corner > > BOX > $w > [1] 1.002451 > > $h > [1] 0.5872093 > > $left > [1] 2.598775 > > $top > [1] 0.5372093 > > > Now, using BOX$left, which defines the x axis value for the left side of > the legend box that is centered, we can call legend() a second time and > adjust the y axis value of the legend to place it outside the plot region, > below the plot. Just be sure that your second call to legend() is exactly > the same as the first call, other than setting legend to FALSE in the first > case. Any change in legend content between the two calls will alter the > size and position of the enclosing box. > > par(xpd = TRUE) > legend(BOX$left, y = -0.25, legend = c("Label 1", "Label 2")) > > > You can then adapt that basic approach to use in your code. > > As an FYI, see ?par and note "usr", which defines the coordinates of the > plot region. If desired, you can get the midpoint of the x axis using: > > mean(par("usr")[1:2]) > > Regards, > > Marc Schwartz[[alternative HTML version deleted]]
Hi Antonio, First you want the center of the plot: xylim<-par("usr") x_center<-sum(xylim[1:2])/2 Then as you want to have you legend above the plot: # you will probably want to change the "20" to your preference y_bottom<-xylim[4]+diff(xylim[3:4])/20 then: legend(x_center,ybottom,...xjust=0.5,yjust=0) Jim On Fri, May 12, 2017 at 4:36 AM, Antonio Silva <aolinto.lst at gmail.com> wrote:> Hello r-users > > I want to plot some barplots inside a looping with the legend placed > outside the plotting area. > > No matter the number of bars I want the legend to be placed centered on the > x-axis. > > See the example below > > for(i in 1:10) { > var_1 <- sample(1000:100000,sample(3:8,1)) > ymax <- max(var_1) > b<-barplot(var_1,col="blue") > var_2 <- sample(1000:ymax,length(var_1)) > lines(rowSums(b),var_2,type="o",col="red",pch=16) > par(xpd=TRUE) > legend(*1.1* > ,ymax*-0.072,c("var_1","var_2"),horiz=T,cex=1.3,bty="n",pch=c(15,16),col=c("blue","red"),lty=c(0,1),lwd=c(0,2),pt.cex=2) > readline(prompt="Press [enter] to continue") > } > > What I should use as x position in legend(x,y, ...), instead of *1.1*, to > have the legend centered on the x-axis? > > I would love to use something like legend(x="center",y=ymax*-0.072, ... but > it did not worked. > > I appreciate any suggestions. Best regards. > > Antonio > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > 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.
On 11/05/2017 2:36 PM, Antonio Silva wrote:> Hello r-users > > I want to plot some barplots inside a looping with the legend placed > outside the plotting area. > > No matter the number of bars I want the legend to be placed centered on the > x-axis. > > See the example below > > for(i in 1:10) { > var_1 <- sample(1000:100000,sample(3:8,1)) > ymax <- max(var_1) > b<-barplot(var_1,col="blue") > var_2 <- sample(1000:ymax,length(var_1)) > lines(rowSums(b),var_2,type="o",col="red",pch=16) > par(xpd=TRUE) > legend(*1.1* > ,ymax*-0.072,c("var_1","var_2"),horiz=T,cex=1.3,bty="n",pch=c(15,16),col=c("blue","red"),lty=c(0,1),lwd=c(0,2),pt.cex=2) > readline(prompt="Press [enter] to continue") > } > > What I should use as x position in legend(x,y, ...), instead of *1.1*, to > have the legend centered on the x-axis? > > I would love to use something like legend(x="center",y=ymax*-0.072, ... but > it did not worked. > > I appreciate any suggestions. Best regards.Instead of "center", use "top" or "bottom". See the 2nd last example in examples(legend) for the possibilities. If you want the legend outside the plotting area, set "inset" and "xpd" arguments. For example, plot(1,1) legend("top", pch = 1, legend = "point", inset = -0.1, xpd = TRUE) Duncan Murdoch
> On May 11, 2017, at 7:01 PM, Duncan Murdoch <murdoch.duncan at gmail.com> wrote: > > On 11/05/2017 2:36 PM, Antonio Silva wrote: >> Hello r-users >> >> I want to plot some barplots inside a looping with the legend placed >> outside the plotting area. >> >> No matter the number of bars I want the legend to be placed centered on the >> x-axis. >> >> See the example below >> >> for(i in 1:10) { >> var_1 <- sample(1000:100000,sample(3:8,1)) >> ymax <- max(var_1) >> b<-barplot(var_1,col="blue") >> var_2 <- sample(1000:ymax,length(var_1)) >> lines(rowSums(b),var_2,type="o",col="red",pch=16) >> par(xpd=TRUE) >> legend(*1.1* >> ,ymax*-0.072,c("var_1","var_2"),horiz=T,cex=1.3,bty="n",pch=c(15,16),col=c("blue","red"),lty=c(0,1),lwd=c(0,2),pt.cex=2) >> readline(prompt="Press [enter] to continue") >> } >> >> What I should use as x position in legend(x,y, ...), instead of *1.1*, to >> have the legend centered on the x-axis? >> >> I would love to use something like legend(x="center",y=ymax*-0.072, ... but >> it did not worked. >> >> I appreciate any suggestions. Best regards. > > Instead of "center", use "top" or "bottom". See the 2nd last example in examples(legend) for the possibilities. > > If you want the legend outside the plotting area, set "inset" and "xpd" arguments. For example, > > plot(1,1) > legend("top", pch = 1, legend = "point", inset = -0.1, xpd = TRUE) > > > Duncan MurdochBingo. The 'inset' argument is what I was missing. That allows this to be done with one step, rather than the two that I had. Thanks Duncan. Marc