Search code examples
rplottextgraphics

Wrapping / bending text around a circle in plot


Is there any chance to write text which is "wrapped" around the circle? I mean something like this:enter image description here


Solution

  • plotrix::arctext

    library(plotrix)
    
    # set up a plot with a circle
    plot(x = 0, y = 0, xlim = c(-2, 2), ylim = c(-2, 2))
    draw.circle(x = 0, y = 0, radius = 1)
    
    # add text
    arctext(x = "wrap some text", center = c(0, 0), radius = 1.1, middle = pi/2)
    arctext(x = "counterclockwise", center = c(0, 0), radius = 1.1, middle = 5*pi/4,
            clockwise = FALSE, cex = 1.5)
    arctext(x = "smaller & stretched", center = c(0, 0), radius = 1.1, middle = 2*pi ,
            cex = 0.8, stretch = 1.2)
    

    enter image description here


    circlize

    For greater opportunities of customization, check the circlize package (see the circlize book). By setting facing = "bending" in circos.text, the text wraps around a circle.

    library(circlize)
    
    # create some angles, labels and their corresponding factors
    # which determine the sectors 
    deg <- seq(from = 0, to = 300, by = 60)
    lab <- paste("some text", deg, "-", deg + 60)   
    factors <- factor(lab, levels = lab)
    
    # initialize plot
    circos.par(gap.degree = 10)
    circos.initialize(factors = factors, xlim = c(0, 1))
    circos.trackPlotRegion(ylim = c(0, 1))
    
    # add text to each sector  
    lapply(factors, function(deg){
      circos.updatePlotRegion(sector.index = deg, bg.col = "red")
    circos.text(x = 0.5, y = 0.5, labels = as.character(deg), facing = "bending")
    })
    circos.clear()
    

    enter image description here

    From circlize version 0.2.1, circos.text has two new options: bending.inside which is identical to original bending and bending.outside (see Figure 3.4 in the circlize book). Thus, it is easy to turn the text in the bottom half of the plot using bending.outside:

    circos.par(gap.degree = 10)
    circos.initialize(factors = factors, xlim = c(0, 1))
    circos.trackPlotRegion(ylim = c(0, 1))
    
    lapply(factors[1:3], function(deg){
      circos.updatePlotRegion(sector.index = deg, bg.col = "red")
      circos.text(x = 0.5, y = 0.5, labels = as.character(deg), facing = "bending.outside")
    })
    
    lapply(factors[4:6], function(deg){
      circos.updatePlotRegion(sector.index = deg, bg.col = "red")
      circos.text(x = 0.5, y = 0.5, labels = as.character(deg), facing = "bending.inside")
    })
    circos.clear()
    

    enter image description here