There might be an easier way to do this, but here’s one way to plot gradients in R. It draws on `colorRampPalette()` and a `for()` loop, and isn’t very fast on underpowered machines — but it works. Using `colorRampPalette()` we can create the necessary gradients. Here’s the code I cobbled together:
``` fade <- function(M=1, S=1, Y=1, H=0.05, K=50, dk = "black") { # M = midpoint; S = spread; Y = position; H = height; K = steps in gradient; dk = dark colour colfunc <- colorRampPalette(c(dk, "white")) # creates a function to produce the gradients D <- S/K # delta; how wide does one rectangle have to be? collist <- colfunc(K) # create K colours for(i in 0:(K-1)) { # draw rectangles; K-1 because I start with 0 (this makes it easier in the line just below) rect(M+(D*i), Y-H, M+D+(D*i), Y+H, col=collist[i+1], border=NA) # drawing a narrow rectangle, no borders drawn; to right rect(M-(D*i), Y-H, M-D-(D*i), Y+H, col=collist[i+1], border=NA) # to left } } ```

Before applying the above code, we need an empty plot:

```plot(1, ylim=c(0.5,8), xlim=c(1,8), type="n", axes=F, xlab="", ylab="") ```

Important are the `ylim` and `xlim` arguments, and the `type="n"` to plot nothing. I usually prefer drawing my own axes — `axis(1)`, `axis(2)` as this allows easy customization…

Why not highlight the midpoint? We can this as follows:

`text(M, Y, "|", col="white", font=4) # font = 4 for bold face`

In many cases, the package denstrip may offer an easier solution, albeit one where we have less control.

P.S. The code produces just one of the lines in the plot included at the top.

## Using Shading in Coefficient Plots

Having recently discovered the R package denstrip, I was struck by intuitive it is to use shading to express uncertainty. If you need convincing, check out the paper by Jennifer Lundquist and Ken Lin linked below.

I wondered whether this would also work well for generic coefficient plots to examine regression results. The proof is in the pudding, so here’s some quickly thrown together code (also on Gist).

```library(denstrip) fade <- function(x, labels=names(coef(x)), expo=FALSE, xlab="", ylab="", bty="n", ...) { # argument: a regression, additional arguments passed on to plot() and text() coe <- summary(x)\$coefficients[,1] # extract coefficients cse <- summary(x)\$coefficients[,2] # standard errors len <- length(coe) # how many coefficients (without intercept) if(expo == TRUE) { # exponential form coe <- exp(coe) cse <- exp(cse) } ran <- c(min(coe)- 3*max(cse), max(coe)+3*max(cse)) # range of values plot(0, ylim=c(1.5,len+0.5), xlim=ran, xlab=xlab, ylab=ylab, bty=bty, type="n", ..., axes=FALSE) # empty plot # title, xlab, ylab, etc. can be used here. for(i in 2:len) { dens <- rnorm(mean=coe[i], sd=cse[i], n=1000) denstrip(dens, at=i) # passing arguments conflicts with plot() text(ran[1],i, labels[i], adj = c(0,0), ...) # adj to left-align # cex, col can be used here } axis(1) } ```

Well, it does work (see figure above). If we add an `abline(v=0, lty=3)`, we can easily highlight the zero line.

However, intuitive as it is, I’m not really convinced. Here’s the coefficient plot the arm package produces. While it doesn’t use shading, lines of different thickness are used to indicate the standard errors — nicely de-emphasizing the end-point. There’s more emphasis on the point estimate (i.e. the coefficient itself: the square), while my code hides this. I did try adding a white line at the point estimate (third figure, below), but this doesn’t resolve my biggest worry: the amount of ink that is used to convey the message… I’m just not convinced that the shading adds that much to the relatively simple coefficient plots in the package arm.

(There’s an argument `width` that could be added to line calling `denstrip`, like `width=0.2`, but it hasn’t convinced me enough.)

Jackson, Christopher H. 2008. “Displaying Uncertainty with Shading.” The American Statistician 62 (4): 340–47. doi:10.1198/000313008X370843.

Lundquist, Jennifer H., and Ken-Hou Lin. 2015. “Is Love (Color) Blind? The Economy of Race among Gay and Straight Daters.” Social Forces, March, sov008. doi:10.1093/sf/sov008.