From: Dan Bolser <dmb_at_mrc-dunn.cam.ac.uk>

Date: Fri 22 Jul 2005 - 21:42:07 EST

R-help@stat.math.ethz.ch mailing list

https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html Received on Fri Jul 22 21:48:21 2005

Date: Fri 22 Jul 2005 - 21:42:07 EST

On Thu, 21 Jul 2005, Marc Schwartz (via MN) wrote:

>[Note: the initial posts have been re-arranged to attempt to maintain

*>the flow from top to bottom]
**>
**>> >Dan Bolser writes:
**>> > >
**>> > > I would like to annotate my plot with a little box containing the slope,
**>> > > intercept and R^2 of a lm on the data.
**>> > >
**>> > > I would like it to look like...
**>> > >
**>> > > +----------------------------+
**>> > > | Slope : 3.45 +- 0.34 |
**>> > > | Intercept : -10.43 +- 1.42 |
**>> > > | R^2 : 0.78 |
**>> > > +----------------------------+
**>> > >
**>> > > However I can't make anything this neat, and I can't find out how to
**>> > > combine this with symbols for R^2 / +- (plus minus).
**>> > >
**>> > > Below is my best attempt (which is franky quite pour). Can anyone
**>> > > improve on the below?
**>> > >
**>> > > Specifically,
**>> > >
**>> > > aligned text and numbers,
**>> > > aligned decimal places,
**>> > > symbol for R^2 in the text (expression(R^2) seems to fail with
**>> > > 'paste') and +-
**>> > >
**>> > >
**>> > >
**>> > > Cheers,
**>> > > Dan.
**>> > >
**>> > >
**>> > > dat.lm <- lm(dat$AVG_CH_PAIRS ~ dat$CHAINS)
**>> > >
**>> > > abline(coef(dat.lm),lty=2,lwd=1.5)
**>> > >
**>> > >
**>> > > dat.lm.sum <- summary(dat.lm)
**>> > > dat.lm.sum
**>> > >
**>> > > attributes(dat.lm.sum)
**>> > >
**>> > > my.text.1 <-
**>> > > paste("Slope : ", round(dat.lm.sum$coefficients[2],2),
**>> > > "+/-", round(dat.lm.sum$coefficients[4],2))
**>> > >
**>> > > my.text.2 <-
**>> > > paste("Intercept : ", round(dat.lm.sum$coefficients[1],2),
**>> > > "+/-", round(dat.lm.sum$coefficients[3],2))
**>> > >
**>> > > my.text.3 <-
**>> > > paste("R^2 : ", round(dat.lm.sum$r.squared,2))
**>> > >
**>> > > my.text.1
**>> > > my.text.2
**>> > > my.text.3
**>> > >
**>> > >
**>> > > ## Add legend
**>> > > text(x=3,
**>> > > y=300,
**>> > > paste(my.text.1,
**>> > > my.text.2,
**>> > > my.text.3,
**>> > > sep="\n"),
**>> > > adj=c(0,0),
**>> > > cex=1
**>
**>
**>> On Thu, 21 Jul 2005, Christoph Buser wrote:
**>>
**>> >Dear Dan
**>> >
**>> >I can only help you with your third problem, expression and
**>> >paste. You can use:
**>> >
**>> >plot(1:5,1:5, type = "n")
**>> >text(2,4,expression(paste("Slope : ", 3.45%+-%0.34, sep = "")), pos = 4)
**>> >text(2,3.8,expression(paste("Intercept : ", -10.43%+-%1.42)), pos = 4)
**>> >text(2,3.6,expression(paste(R^2,": ", "0.78", sep = "")), pos = 4)
**>
**>> >I do not have an elegant solution for the alignment.
**>
**>
**>On Thu, 2005-07-21 at 19:55 +0100, Dan Bolser wrote:
**>> Cheers for this.
**>>
**>> I was trying to get it to work, but the problem is that I need to replace
**>> the values above with variables, from the following code...
**>>
**>>
**>> dat.lm <- lm(dat$AVG_CH_PAIRS ~ dat$CHAINS)
**>> dat.lm.sum <- summary(dat.lm)
**>>
**>> my.slope.1 <- round(dat.lm.sum$coefficients[2],2)
**>> my.slope.2 <- round(dat.lm.sum$coefficients[4],2)
**>>
**>> my.inter.1 <- round(dat.lm.sum$coefficients[1],2)
**>> my.inter.2 <- round(dat.lm.sum$coefficients[3],2)
**>>
**>> my.Rsqua.1 <- round(dat.lm.sum$r.squared,2)
**>>
**>>
**>> Anything I try results in either the words 'paste("Slope:", my.slope.1,
**>> %+-%my.slope.2,sep="")' being written to the plot, or just
**>> 'my.slope.1+-my.slope2' (where the +- is correctly written).
**>>
**>> I want to script it up and write all three lines to the plot with
**>> 'sep="\n"', rather than deciding three different heights.
**>
**>
**>> Thanks very much for what you gave, its a good start for me to figure out
**>> how I am supposed to be telling R what to do!
**>>
**>> Any way to just get fixed width fonts with text? (for the alignment
**>> problem)
**>
**>
**>Dan,
**>
**>Here is one approach. It may not be the best, but it gets the job done.
**>You can certainly take this and encapsulate it in a function to automate
**>the text/box placement and to pass values as arguments.
**>
**>A couple of quick concepts:
**>
**>1. As far as I know, plotmath cannot do multiple lines, so each line in
**>your box needs to be done separately.
**>
**>2. The horizontal alignment is a bit problematic when using expression()
**>or bquote() since I don't believe that multiple spaces are honored as
**>such after parsing. Thus I break up each component (label, ":" and
**>values) into separate text() calls. The labels are left justified.
**>
**>3. The alignment for the numeric values are done with right
**>justification. So, as long as you use a consistent number of decimals in
**>the value outputs (2 here), you should be OK. This means you might need
**>to use formatC() or sprintf() to control the numeric output values on
**>either side of the +/- sign.
**>
**>4. In the variable replacement, note the use of substitute() and the
**>list of x and y arguments as replacement values in the expressions.
**>
**>
**>
**># Set your values
**>my.slope.1 <- 3.45
**>my.slope.2 <- 0.34
**>
**>my.inter.1 <- -10.43
**>my.inter.2 <- 1.42
**>
**>my.Rsqua <- 0.78
**>
**>
**># Create the initial plot as per Christoph's post
**>plot(1:5, 1:5, type = "n")
**>
**>
**>#-------------------------------------
**># Do the Slope
**>#-------------------------------------
**>
**>text(1, 4.5, "Slope", pos = 4)
**>text(2, 4.5, ":")
**>text(3, 4.5, substitute(x %+-% y,
**> list(x = my.slope.1,
**> y = my.slope.2)),
**> pos = 2)
**>
**>
**>#-------------------------------------
**># Do the Intercept
**>#-------------------------------------
**>
**>text(1, 4.25, "Intercept", pos = 4)
**>text(2, 4.25, ":")
**>text(3, 4.25, substitute(x %+-% y,
**> list(x = my.inter.1,
**> y = my.inter.2)),
**> pos = 2)
**>
**>
**>#-------------------------------------
**># Do R^2
**>#-------------------------------------
**>
**>text(1, 4.0, expression(R^2), pos = 4)
**>text(2, 4.0, ":")
**>text(3, 4.0, substitute(x, list(x = my.Rsqua)),
**> pos = 2)
**>
**>
**>#-------------------------------------
**># Do the Box
**>#-------------------------------------
**>
**>rect(1, 3.75, 3, 4.75)
**>
**>
**>You can adjust the x,y coordinates for the various text elements as you
**>may require and can also calculate them based upon the xlim, ylim of
**>your actual plot. You can also modify the 'cex' argument to text() for
**>adjusting the sizes of the fonts in use.
*

I have been trying many different combinations of the suggestions so far...

bquote, substitute, expression, paste, etc.

Also I was trying to use the 'expression' part of the 'legend' function to make thing easier (make new lines, make columns, make rectangles)...

So far all in vain.

I am sure a fairly neat solution is possible using 'legend' and 'expression', but I cant get a legend which contains a variable substituted value *and* a special symbol.

Can anyone show me an example of this simple step, and then I can try to build on that.

Thanks all for suggestions, its one of those 'it seems so easy' problems (for me).

P.S. Whats with the documentation for bquote?

>BTW, to use a monospaced font, you can set par(family = "mono").

*>See ?par for more information.
**>
**>HTH,
**>
**>Marc Schwartz
**>
**>
*

R-help@stat.math.ethz.ch mailing list

https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html Received on Fri Jul 22 21:48:21 2005

*
This archive was generated by hypermail 2.1.8
: Fri 03 Mar 2006 - 03:33:55 EST
*