[R] Format of numbers in plotmath expressions.
William Dunlap
wdunlap at tibco.com
Sun Oct 7 22:04:32 CEST 2012
In-line comments below.
Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf
> Of Rolf Turner
> Sent: Friday, October 05, 2012 5:02 PM
> To: Uwe Ligges
> Cc: r-help at r-project.org
> Subject: Re: [R] Format of numbers in plotmath expressions.
>
>
>
> Thanks Uwe. I think your recipe is substantially sexier than mine.
>
> However I will, I believe, ***NEVER*** understand how to put together
> plotmath constructs. They seem to require some subset of:
>
> * expression()
> * bquote()
> * substitute()
> * parse()
Note that using parse was one source of your original problem. You did
the equivalent of
parse(text=paste("theta", "1.0000", sep="=="))
which gives the same result as
parse(text=paste("theta", "1", sep="=="))
because "x==1.0000" and "x==1" should be parsed to be the same expression.
If you wanted the string "1.0000" to come out of parse then you would have
to quote it, as in
legend("topleft",pch=1:5,legend=parse(text=paste0("theta == \"",TH,"\"")))
instead of your original
legend("topleft",pch=1:5,legend=parse(text=paste0("theta == ", TH)))
This works because plotmath does not render the quotes in strings.
I would recommend taking parse(), paste(), substitute(), and even expression() off
your list of things to try when using plotmath. For single chunks of plotmath text,
isn't bquote() sufficient? For multiple chunks (e.g., the strings given to legend or axis)
I think you can restrict yourself to the idiom
as.expression(lapply(data, function(d)bquote(...)))
mapply would be fine here also, but I would avoid sapply, as its simplification algorithm
can surprise you. expression() is good when you have a fixed (parameterless)
expression you want to display, but bquote is just as good, so don't bother thinking
about using expression() in plotmath.
Here is an example of mapply used to make axis tick labels of the form
num * pi / den, leaving out unneeded 1's, and related legend labels:
curve(sin, from=0, to=6.5, axes=FALSE)
num <- 0:8 ; den <- 4 # want labels num * pi / den, simplified when possible
labs <- as.expression(mapply(num, den, SIMPLIFY=FALSE, FUN=function(n, d)
{
gcd <- function(a,b) ifelse (b==0, a, gcd(b, a %% b))
div <- gcd(n, d)
if (div > 1) {
n <- n / div ; d <- d / div
}
if (n==0) {
bquote(0)
} else if (d==1) {
if (n==1) {
bquote(pi)
} else {
bquote(.(n)*pi)
}
} else {
if (n==1) {
bquote(pi/.(d))
} else {
bquote(.(n)*pi/.(d))
}
}
}
))
axis(side=1, at=num*pi/den, lab=labs)
# Now put theta= on the front of each label for the legend
legend("bottomleft", as.expression(lapply(labs, function(lab)bquote(theta==.(lab)))))
I am not an expert on plotmath, but my feeling from watching people use
it is that they tend to lose track of the boundary between standard R functions
and the functions by the same name used by plotmath for different purposes
By sticking to using bquote() for creating single plotmath exressions and
as.expression(lapply(..., function(x)bquote(.(x)))) for collections of plotmath
expressions, you can concentrate on the learning the plotmath language itself.
Are there plotmath expressions that cannot be made with bquote instead of
parse(text=paste(...))? Perhaps not, but some with a variable number of
components may be more easily done with parse.
> * paste()
> * as.expression()
> * .(...)
>
> (and quite possibly other things that I have forgotten) in a bewildering
> variety of combinations with no perceptible rationale as what combination
> is required in what circumstances.
>
> It makes quantum mechanics look simple by comparison.
>
> cheers,
>
> Rolf
>
> On 06/10/12 06:58, Uwe Ligges wrote:
> >
> >
> > On 05.10.2012 09:30, Rolf Turner wrote:
> >>
> >> I want to do something like:
> >>
> >> TH <- sprintf("%1.1f",c(0.3,0.5,0.7,0.9,1))
> >> plot(1:10)
> >> legend("bottomright",pch=1:5,legend=parse(text=paste("theta ==",TH)))
> >>
> >> Notice that the final "1" comes out in the legend as just plain "1"
> >> and NOT
> >> as "1.0" although TH is
> >>
> >> [1] "0.3" "0.5" "0.7" "0.9" "1.0"
> >>
> >> I can get plotmath to preserve "1.0" as "1.0" and NOT convert it to "1"
> >> if I use substitute, as in
> >>
> >> text(2,5,labels=substitute(list(theta == a),list(a=TH[5])))
> >>
> >> but substitute doesn't work appropriately with vectors.
> >>
> >> Can anyone tell me how to get a "1.0" rather than "1" in the legend?
> >>
> >> Ta.
> >>
> >> cheers,
> >>
> >> Rolf Turner
> >>
> >> P.S. Just figured out a way using sapply():
> >>
> >> leg <- sapply(TH,function(x){substitute(list(theta == a),list(a=x))})
> >> plot(1:10)
> >> legend("bottomright",pch=1:5,legend=parse(text=leg))
> >>
> >> Note that the use of "parse" (pace Thomas Lumley! :-) ) is required ---
> >> "legend=leg" does NOT work.
> >>
> >> Getting here required an enormous amount of trial and error. And it
> >> seems
> >> pretty kludgy.
> >>
> >> Is there a sexier way?
> >
> >
> > Not sure what is sexier here. I'd stay with
> >
> > leg <- lapply(TH, function(x) bquote(list(theta == .(x))))
> > plot(1:10)
> > legend("bottomright", pch=1:5, legend=as.expression(leg))
> >
> >
> > Best,
> > Uwe Ligges
> >
> >
> >
> >>
> >> R. T.
> >>
> >> ______________________________________________
> >> R-help at 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 at 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.
More information about the R-help
mailing list