【问题标题】:R plots: Is there a way to draw a border, shadow or buffer around text labels?R plots:有没有办法在文本标签周围绘制边框、阴影或缓冲区?
【发布时间】:2014-10-27 04:20:09
【问题描述】:

我想在单色图形的一条线上绘制一个标签。所以我需要在标签的每个字母上加上白色的小边框。

文本标签的矩形边框或背景没有用,因为它隐藏了很多绘制的数据。

有没有办法在 R 图中的文本标签周围放置边框、阴影或缓冲区?

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 solution from koekenbakker。这对于 PNG 图形来说很好,但是对于高分辨率 PDF,我需要一种不同的方法。

【问题讨论】:

  • R 中有许多不同的绘图功能和图形系统。请更具体地说明您当前使用的绘图命令。更好的是,包括reproducible example
  • pdf 有什么问题?你是说分辨率?您可以调整 theta 参数以获得更高的分辨率。我会在我的回答中改变这一点。
  • 你是对的。在我的示例中,我尝试了 24 个项目的 theta,但还不够。但是在您的示例中,50 可以完美运行。谢谢

标签: r plot text label


【解决方案1】:

您可以尝试使用这种“shadowtext”功能,通过将文本打印几次并以不同的颜色稍微偏移来在文本周围绘制一个光环或边框。所有致谢Greg Snow 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()

【讨论】:

  • 太棒了!想知道类似的东西是否可以适用于多行文本。 On 可以肯定地使用 xpd=T 来调整它,但是很容易使用它在页边空白处写标题和图例会很好!
【解决方案2】:

我为文本字段编写了一个类似的函数,它也适用于对数刻度。

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

这对于矢量图形来说可能会更好。 以下是一些示例:

PS:如果你想投稿:https://github.com/brry/berryFunctions

【讨论】:

    【解决方案3】:

    这是我在标记轮廓(或本例中的圆圈)时添加文本缓冲区的尝试。它绝对不如koekenbakker's solution 有效或漂亮,但它起到了我将文本标签与行隔离开来的目的。

    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 want 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
    

    【讨论】:

      【解决方案4】:

      我需要为 R 中的地图执行此操作,最后使用“raster”包在文本标签周围绘制光晕。

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

      例如,

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

      【讨论】:

        【解决方案5】:

        shadowtext 包可用于在 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()
        

        reprex package (v0.2.1.9000) 于 2018 年 10 月 14 日创建

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-22
          相关资源
          最近更新 更多