我想在单色图形中的一条线上绘制标签。所以我需要在标签的每个字母上留下小的白色边框。
文本标签的矩形边框或背景无用,因为隐藏了大量绘制的数据。
有没有办法在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()
上面的代码使用koekenbakker的解决方案。这适用于PNG图形,但我需要一种不同的高分辨率PDF方法。
答案 0 :(得分:14)
您可以尝试这种'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()
答案 1 :(得分:9)
我需要为R中的地图执行此操作,最后使用“raster”包在文本标签周围绘制光晕。
http://rpackages.ianhowson.com/cran/raster/man/text.html
如,
text(Points, labels = Points$Labels, halo = TRUE, hw = 0.08, hc = "white", cex = 0.8)
# hw = halo width
# hc = halo color
答案 2 :(得分: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创建
答案 3 :(得分:1)
我为文本字段编写了一个类似的函数,它也适用于对数刻度。
install.packages("berryFunctions")
library("berryFunctions")
?textField
对于矢量图形,这可能被认为更好。 以下是一些例子:
PS:如果你想贡献:https://github.com/brry/berryFunctions
答案 4 :(得分:1)
这是我尝试在标记轮廓(或本例中的圆圈)时添加文本缓冲区。它绝对不如koekenbakker的解决方案那么有效或漂亮,但它的目的是让我将文本标签与行隔离。
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