4

I want to add several lines of text to a plot, in which some words are in italics. This is what the text should look like:

Italic Text: Some
words with
new lines.

More italic text: Yet
more words divided
by new lines.

Italics again: And more
text with
new lines.

The following code prints a single line of text with italic words:

plot(c(0, 2), c(0, 2))
text(1, 1, bquote(
        paste(
            italic("Italic Text:"),
            " Some words with new lines. ",
            italic("More italic text:"),
            "Yet more words divided by new lines. ",
            italic("Italics again:"),
            "And more text with new lines.",
            sep = ""
        )
    )
)

enter image description here

And this creates line breaks, but no italics:

plot(c(0, 2), c(0, 2))
text(1, 1, "Italic Text: Some\nwords with\nnew lines.\n\nMore italic text: Yet\nmore words divided\nby new lines.\n\nItalics again: And more\ntext with\nnew lines.")

enter image description here

But when I try to break the text into lines and add italics, the newline characters lead to strange results:

plot(c(0, 2), c(0, 2))
text(1, 1, bquote(
        paste(
            italic("Italic Text:"),
            " Some\nwords with\nnew lines.\n\n",
            italic("More italic text:"),
            "Yet\nmore words divided\nby new lines.\n\n",
            italic("Italics again:"),
            "And more\ntext with\nnew lines.",
            sep = ""
        )
    )
)

enter image description here

atop(), as suggested in other answers, only works with two lines.

What's the easiest method to add multiple lines of text with several words in italics to a plot?

  • Ideally, using only base R.
  • And without painfully positioning each line of text separately.

3 Answers3

3

We can use substitute() to combine italic and normal text. To left align the text we can use option pos=4. then we can we can fiddle it together like this.

plot(c(0, 2), c(0, 2))
text(1, 1.9, substitute(paste(italic("Italic:"), " Some")), pos=4)
text(1, 1.7, "words with\nnew lines.", pos=4)
text(1., 1.4, substitute(paste(italic("More italic text:"), " Yet")), pos=4)
text(1, 1.21, "words with\nnew lines.", pos=4)
text(1., .9, substitute(paste(italic("Italics again:"), " And more")), pos=4)
text(1, .71, "text with\nnew lines.", pos=4)

enter image description here

Note: It shifts a little bit while exporting. I've exported the figure with 500x500 resolution.

jay.sf
  • 60,139
  • 8
  • 53
  • 110
  • Thank you, but that's the kind of fiddling I want to avoid. I'd like to place a *block of text* of multiple lines, as can be easily done with `text(x, y, "Text\nwith\nline\nbreaks.")`. –  Feb 18 '19 at 05:08
2

How about this?

plot(c(0, 10), c(0, 10))
text(
  5,
  7:2,
  c(
    expression(paste(italic("Italic Text:"), " Some")),
    "\nwords with\nnew lines.",
    expression(paste(italic("More italic text:"), " Yet")),
    "\nmore words divided\nby new lines.",
    expression(paste(italic("Italics again:"), "And more")),
    "\ntext with\nnew lines."
  )
)

enter image description here

i think what is happening is what is mentioned in the vignette for text.

If labels is longer than x and y, the coordinates are recycled to the length of labels

That could be the reason why you are getting your weird layout. If you change my 7:2 code inside text, I also get your "messed up" layout. Only the center paragraph looks still "off" - and I am really not sure why... It looks the same as the other 2 :-s. The rest looks spot on what you are looking for, I take it? In any case, looks exactly like your second picture, which I used as my reference point...

I just fondled some more with this.. if you want left-justified, just add pos = 4 inside the text function.

enter image description here

From here on, you should be able to get precisely what you want. Hope this helps!

tchevrier
  • 1,041
  • 7
  • 16
0

I don't know the italic job...but that package I wrote could help you:

devtools::install_github("igorkf/breaker")
library(breaker)

nbreak("Some text that you want and the italic stuff", n = 3)
#[1] "Some text that\nyou want and\nthe italic stuff"

#You can also use this with purrr:
purrr::map_chr(list("the first text that you want",
                    "the second text that you want",
                    "the third text that you want"),
                  ~nbreak(.x, n = 2))
#[1] "the first\ntext that\nyou want"  "the second\ntext that\nyou want" "the third\ntext that\nyou want"

You can also only break a once using loop = F

igorkf
  • 3,159
  • 2
  • 22
  • 31