Ben
Ben

Reputation: 319

Change color of labels and tick marks in pie chart in Base R

I have a pie chart:

x <- c(30, 70)
pie(x)

I want the labels to be red and the tick marks to be either red or transparent. How do I do that? xaxt = "n" and col.axis = "red" seem to have no effect.

pie(x, xaxt = "n", col.axis = "red")

Upvotes: 3

Views: 55

Answers (2)

jay.sf
jay.sf

Reputation: 72543

@Edward's solution is great. For even more flexibility we could "hack" the pie function, something like:

> pie_hack <- 
+   function (x, labels = names(x), edges = 200, radius = 0.8, clockwise = FALSE, 
+             init.angle = if (clockwise) 90 else 0, density = NULL, angle = 45, 
+             col = NULL, border = NULL, lty = NULL, main = NULL, 
+             ticks.col = NULL, ticks.lab.col = NULL, ...) {
+     if (!is.numeric(x) || any(is.na(x) | x < 0)) 
+       stop("'x' values must be positive.")
+     if (is.null(labels)) 
+       labels <- as.character(seq_along(x))
+     else labels <- as.graphicsAnnot(labels)
+     x <- c(0, cumsum(x)/sum(x))
+     dx <- diff(x)
+     nx <- length(dx)
+     plot.new()
+     pin <- par("pin")
+     xlim <- ylim <- c(-1, 1)
+     if (pin[1L] > pin[2L]) 
+       xlim <- (pin[1L]/pin[2L]) * xlim
+     else ylim <- (pin[2L]/pin[1L]) * ylim
+     dev.hold()
+     on.exit(dev.flush())
+     plot.window(xlim, ylim, "", asp = 1)
+     if (is.null(col)) 
+       col <- if (is.null(density)) 
+         c("white", "lightblue", "mistyrose", "lightcyan", 
+           "lavender", "cornsilk")
+     else par("fg")
+     if (!is.null(col)) 
+       col <- rep_len(col, nx)
+     if (!is.null(border)) 
+       border <- rep_len(border, nx)
+     if (!is.null(lty)) 
+       lty <- rep_len(lty, nx)
+     angle <- rep(angle, nx)
+     if (!is.null(density)) 
+       density <- rep_len(density, nx)
+     twopi <- if (clockwise) 
+       -2 * pi
+     else 2 * pi
+     t2xy <- function(t) {
+       t2p <- twopi * t + init.angle * pi/180
+       list(x = radius * cos(t2p), y = radius * sin(t2p))
+     }
+     for (i in 1L:nx) {
+       n <- max(2, floor(edges * dx[i]))
+       P <- t2xy(seq.int(x[i], x[i + 1], length.out = n))
+       polygon(c(P$x, 0), c(P$y, 0), density = density[i], angle = angle[i], 
+               border = border[i], col = col[i], lty = lty[i])
+       P <- t2xy(mean(x[i + 0:1]))
+       lab <- as.character(labels[i])
+       if (!is.na(lab) && nzchar(lab)) {
+         lines(c(1, 1.05) * P$x, c(1, 1.05) * P$y, 
+               col=if (!is.null(ticks.col)) ticks.col[i] else par("col"))  ## changed
+         text(1.1 * P$x, 1.1 * P$y, labels[i], xpd = TRUE, 
+              adj = ifelse(P$x < 0, 1, 0), 
+              col=if (!is.null(ticks.lab.col)) ticks.lab.col[i] else par("col"))  ## changed
+       }
+     }
+     title(main = main, ...)
+     invisible(NULL)
+   }
> 
> par(mfrow=c(2, 2), mar=c(1, 1, 1, 1))
> pie(x)
> cols <- hcl.colors(length(x))
> pie_hack(x, ticks.col=cols, ticks.lab.col=cols)
> pie_hack(x, ticks.col=c('red', 'blue'), ticks.lab.col=c('green', 'orange'))
> par(col='darkorange')
> pie_hack(x)

enter image description here

Upvotes: 1

Edward
Edward

Reputation: 18493

You can change the colour of the ticks and labels by setting the col graphical parameter first:

opar <- par(col="red")
pie(x)

enter image description here

Then reset the color to the previous setting:

par(opar)

Upvotes: 4

Related Questions