juba
juba

Reputation: 49033

Outlined text with ggplot2

I'd like to know if there is a way to draw "outlined text" with ggplot2, for example black text with a small white border, in order to make it easily readable on backgrounds such as maps.

Ideally I'd like to achieve the same type of labels you can see on Google Maps :

enter image description here

Thanks in advance for any hints !

Upvotes: 43

Views: 17733

Answers (4)

Karol Daniluk
Karol Daniluk

Reputation: 544

Much simplier solution is to use shadowtext library and use geom_shadowtext instead of geom_text

Upvotes: 31

grssnbchr
grssnbchr

Reputation: 2974

The accepted answer by Greg Snow doesn't work anymore with [email protected] because of the call of aes instead of aes_q.

Use

for(i in theta) {
  p <- p + geom_text( 
    aes_q(x = bquote(carat+.(cos(i)*xo)),
          y = bquote(price+.(sin(i)*yo)),
          label = ~cut), 
    size=12, colour='black' )
}

instead.

Upvotes: 2

Greg Snow
Greg Snow

Reputation: 49640

Here is an approach that implements the general idea from the shadowtext function in the TeachingDemos package. The code for the middle part could be wrapped into a function to simplify some things. The example is blatantly stolen from Richie Cotton's answer:

d <- diamonds[sample(nrow(diamonds), 10), ]  


p <- ggplot(d, aes(carat, price) ) 
theta <- seq(pi/8, 2*pi, length.out=16)
xo <- diff(range(d$carat))/200
yo <- diff(range(d$price))/200
for(i in theta) {
    p <- p + geom_text( 
        bquote(aes(x=carat+.(cos(i)*xo),y=price+.(sin(i)*yo),label=cut)), 
                    size=12, colour='black' )
}
p <- p + geom_text( aes(label=cut), size=12, colour='white' )
p <- p + opts( panel.background=theme_rect(fill='green' ) )
print(p)

enter image description here

Upvotes: 16

Richie Cotton
Richie Cotton

Reputation: 121057

Not ideal or very flexible but you can get the effect by drawing bold mono text, then standard mono text on top.

I've used a green panel background to simulate the map.

d <- diamonds[sample(nrow(diamonds), 10), ]

(p <- ggplot(d, aes(carat, price)) +
  geom_text(
    aes(label = cut, family = "mono", fontface = "bold"), 
    size = 12, 
    colour = "black"
  ) +
  geom_text(
    aes(label = cut, family = "mono"), 
    size = 12, 
    colour = "white"
  ) +
  opts(panel.background = theme_rect(fill = "green"))
)

text-on-bold-text with the diamonds dataset

Upvotes: 6

Related Questions