ElMaestro
★★★

Denmark,
2022-04-24 19:09
(32 d 00:30 ago)

Posting: # 22936
Views: 331
 

 text function in R, how to get an idea of width? [Off Topic]

Hi all,

hot greetings from Ahmedabad.

Let's say I do this:

foo=function(s1, s2)
{
  pdf("foopdf1.pdf", height=4, width=3)

  y=c(8,2,3,3,1,2,3,1,9)
  barplot(y)
  rect(2,4,8,6)
  text(2,5, s1, pos=4)
  text(2,4.3, s2, pos=4)

  dev.off()

}

foo("Text is ok", "Text is too wide")
system2('open', args = 'foopdf1.pdf', wait = T)


On my system (and it may indeed be dependent on various factors like devices, resolution, OS and a ton of stuff I know nothing about) I am getting the two labels printed with Arial in the rectangle, and while s1 fits inside the rectangle, s2 doesn't - it extends beyond the rectangle borders to the right.

So here's the challenge:
How can I determine dynamically if any text s2 fits inside the rectangle or not?

I have deliberately chosen not to use specify a fixed-width font family (Courier would otherwise be easy to set). Note also the "useKerning" option of the pdf function which may have some influence on actual text width.

Many thanks for any input.
EM.

Pass or fail!
ElMaestro
Helmut
★★★
avatar
Homepage
Vienna, Austria,
2022-04-24 22:24
(31 d 21:15 ago)

@ ElMaestro
Posting: # 22937
Views: 296
 

 Help is on the way

Hi ElMaestro,

» hot greetings from Ahmedabad.

Hope you enjoy it. ;-)

The problem with your code is that rect() does not – and can not – ‘know’ how wide text() will be.

A workaround:

foo2 <- function(name, h, w, values, loc, cex, lgd) {
  pdf(name, height = 4, width = 3)
  barplot(values, las = 1)
  legend(loc, legend = lgd,
         cex = cex,     # trial & error
         x.intersp = 0, # otherwise, we have a left margin
         trace = TRUE)  # shows user coordinates in the console
  dev.off()
}
name <- "foopdf2.pdf"
foo2(name = name, h = 4, w = 3,
     values = c(8, 2, 3, 3, 1, 2, 3, 1, 9),
     loc = "center", cex = 0.85,
     lgd = c("Text is ok.", "Text is also ok."))
system2("open", args = name, wait = TRUE)


With the additional argument plot = FALSE you could assign all what is needed to a variable:
    rect a list with components
    • w, h
      positive numbers giving width and height of the legend’s box.
    • left, top
      x and y coordinates of upper left corner of the box.
    text a list with components
    • x, y
      numeric vectors of length length(legend), giving the x and y coordinates of the legend's text(s).
Then generate a rectangle which is large enough to contain the text. However, using legend() directly (eventually with x, y coordinates) is much simpler. See the examples at the end of the man page of legend.

Dif-tor heh smusma 🖖 [image]
Helmut Schütz
[image]

The quality of responses received is directly proportional to the quality of the question asked. 🚮
Science Quotes
ElMaestro
★★★

Denmark,
2022-04-25 04:20
(31 d 15:20 ago)

@ Helmut
Posting: # 22938
Views: 260
 

 The width of text is important, not the rectangle

Hi Helmut,

thanks for your response. Perhaps my example was badly illustrated.
I am not trying to create a legend. I am trying to know how wide a text is, even if in the example I have illustrated the matter through something similar to the notion of a legend.

So, more generally:
I need to check if my text can fit within a span of dx units on a plot (dx in my example was the width of a rect, this rect was only for visualisation of the challenge).
If the text fits can then I am happy and if it can't then I need to change certain things, like creating two lines in stead of one (but changing cex is not the appropriate option). dx could also be the space between the two tall bars on the plot, or the entire plot area. And so forth.


Kindly allow me to rephrase:
I have a dynamic text s. I am going to put it on a plot. But I need to know if s at a given set of parameters and setting fits onto the plot within a width of dx units on the horizontal axis as one line. Nothing else.

Pass or fail!
ElMaestro
Helmut
★★★
avatar
Homepage
Vienna, Austria,
2022-04-25 09:26
(31 d 10:13 ago)

@ ElMaestro
Posting: # 22940
Views: 253
 

 I suggest strwidth()

Hi ElMaestro,

» I have a dynamic text s. I am going to put it on a plot. But I need to know if s at a given set of parameters and setting fits onto the plot within a width of dx units on the horizontal axis as one line.

I see. You create the plot first and then strwidth(s) and strheight(s) will give you what you need.

Dif-tor heh smusma 🖖 [image]
Helmut Schütz
[image]

The quality of responses received is directly proportional to the quality of the question asked. 🚮
Science Quotes
UA Flag
Activity
 Admin contact
22,105 posts in 4,630 threads, 1,566 registered users;
online 10 (1 registered, 9 guests [including 6 identified bots]).
Forum time: Thursday 19:40 CEST (Europe/Vienna)

Operational hectic replaces
intellectual calms.    Alexander Huiskes

The Bioequivalence and Bioavailability Forum is hosted by
BEBAC Ing. Helmut Schütz
HTML5