R graph: is there a way to draw a border, shadow, or buffer around text labels?

I want to label a line in a monochrome image. Therefore, I need a small white frame on each letter of the label.

The border or background of the rectangle of the text label is useless because it hides a lot of data plotted on the graph.

Is there a way to put borders, shadows or buffers around text labels on R graphs?

EDIT:

shadowtext <- function(x, y=NULL, labels, col='white', bg='black', theta= seq(pi/4, 2*pi, length.out=8), r=0.1, ... ) { xy <- xy.coords(x,y) xo <- r*strwidth('x') yo <- r*strheight('x') for (i in theta) { text( xy$x + cos(i)*xo, xy$y + sin(i)*yo, labels, col=bg, ... ) } text(xy$x, xy$y, labels, col=col, ... ) } pdf(file="test.pdf", width=2, height=2); par(mar=c(0,0,0,0)+.1) plot(c(0,1), c(0,1), type="l", lwd=20, axes=FALSE, xlab="", ylab="") text(1/6, 1/6, "Test 1") text(2/6, 2/6, "Test 2", col="white") shadowtext(3/6, 3/6, "Test 3") shadowtext(4/6, 4/6, "Test 4", col="black", bg="white") shadowtext(5/6, 5/6, "Test 5", col="black", bg="white", theta = seq(pi/4, 2*pi, length.out=24)) dev.off() 

The code above uses a solution from koekenbakker. This is good for PNG graphics, but I need a different approach for high resolution PDF.

+11
text r plot label
source share
5 answers

You can try this "shadowtext" function, which draws a halo or border around the text, printing it several times with a slight offset in a different color. All Greg Snow loans are here .

 shadowtext <- function(x, y=NULL, labels, col='white', bg='black', theta= seq(0, 2*pi, length.out=50), r=0.1, ... ) { xy <- xy.coords(x,y) xo <- r*strwidth('A') yo <- r*strheight('A') # draw background text with small shift in x and y in background colour for (i in theta) { text( xy$x + cos(i)*xo, xy$y + sin(i)*yo, labels, col=bg, ... ) } # draw actual text in exact xy position in foreground colour text(xy$x, xy$y, labels, col=col, ... ) } # And here is an example of use: # pdf(file="test2.pdf", width=2, height=2); par(mar=c(0,0,0,0)+.1) plot(c(0,1), c(0,1), type="n", lwd=20, axes=FALSE, xlab="", ylab="") rect(xleft = 0.5, xright = 1, ybottom = 0, ytop = 1, col=1) text(1/6, 1/6, "Test 1") shadowtext(2/6, 2/6, "Test 2", col='red', bg="blue") shadowtext(3/6, 3/6, "Test 3", cex=2) # `r` controls the width of the border shadowtext(5/6, 5/6, "Test 4", col="black", bg="white", cex=4, r=0.2) # dev.off() 

enter image description here

+14
source share

I needed to do this for a map in R, and in the end I used the β€œraster” package to draw ghosting around text labels.

http://rpackages.ianhowson.com/cran/raster/man/text.html

eg,

 library(raster) text(Points, labels = Points$Labels, halo = TRUE, hw = 0.08, hc = "white", cex = 0.8) # hw = halo width # hc = halo color 

enter image description here

+10
source share

The shadowtext package can be used to draw a path or shadow around the text for ggplot2 .

 library(ggplot2) library(shadowtext) jet.colors <- colorRampPalette(c("#00007F", "blue", "#007FFF", "cyan", "#7FFF7F", "yellow", "#FF7F00", "red", "#7F0000")) ### Note: jet (rainbow) is not color-blind friendly, not perceptually uniform, and can be misleading # so please don't use it for your plots # https://blogs.egu.eu/divisions/gd/2017/08/23/the-rainbow-colour-map/ # https://www.nature.com/articles/519291d # Choose viridis instead https://cran.r-project.org/web/packages/viridis/vignettes/intro-to-viridis.html # I only use jet here for the demonstration of the 'shadowtext' package. ggplot(faithfuld, aes(waiting, eruptions)) + geom_raster(aes(fill = density)) + scale_fill_gradientn(colors = jet.colors(7)) + geom_shadowtext(aes(x = 75, y = 4.5), label = "White text with black outline\nwill be visible on any background", check_overlap = TRUE, size = 8) + theme_minimal() 

Created in 2018-10-14 by presentation package (v0.2.1.9000)

+6
source share

I wrote a similar function for text fields, which also works with logarithmic scales.

 install.packages("berryFunctions") library("berryFunctions") ?textField 

This may be considered more enjoyable for vector graphics. Here are some examples:

enter image description here

PS: If you want to contribute: https://github.com/brry/berryFunctions

+1
source share

Here is my attempt to add a text buffer when marking outlines (or circles in this example). It is definitely not as effective or beautiful as the koekenbakker solution, but it served me to isolate the text label from the line.

 require(shape) plot(250,250, xlim=c(0,500), ylim=c(0,500), axes=F, ylab="", xlab="", col="black") ## set up the plotting area circle_radius<-c(200, 150, 50) ## we wan't to draw a few circles which we will label after using our buffer for (i in 1:length(circle_radius)){ plotcircle(mid=c(250,250), r=circle_radius[i], lwd=0.5,lcol="grey40") ## iteratively plot the circles text_buffer<-seq(0.1, 0.7, by=0.01) ## this is the key to the text buffer. Create a vector of values to set the character size (cex) during the following loop for(j in text_buffer){ text(x=250+circle_radius[i], 250, print(paste(circle_radius[i],"m")), cex=j, srt=270, col="white") ## write the text buffer in white starting from the smallest value of cex to the largest } ## end of loop for writing buffer text(x=250+circle_radius[i], 250, print(paste(circle_radius[i],"m")), cex=0.5, srt=270) ## write over the buffer with black text } ## end of loop for drawing circles 

Plot of circles with text buffers

+1
source share

All Articles