Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plot gradient circles

Tags:

r

I am attempting to reproduce a Stephen Few graphic with gradient circles that demonstrates the hard wired assumption that light appears from above. Here are the circles:

enter image description here

How can I recreate this? Drawing the circles isn't too bad but adding gradient is where I get thrown. I am thinking grid may create something more crisp but this may be a misconception I have.

Here is the start with drawing circles:

## John Fox circle function
source("http://dl.dropboxusercontent.com/u/61803503/wordpress/circle_fun.txt")

par(mar=rep(1, 4), bg = "grey80")
plot.new()

for (i in seq(0, 1, by = .2)) {
    for (j in seq(.6, 1, by = .1)) {
        circle(i, j, .5, "cm", , 1)
    }
}

Related question: How to use R to build bubble charts with gradient fills

EDIT:

Thought I'd share the results: enter image description here

And here's the code.

like image 787
Tyler Rinker Avatar asked Jun 27 '13 02:06

Tyler Rinker


People also ask

How do you calculate a gradient of a circle?

To find the gradient use the fact that the tangent is perpendicular to the radius from the point it meets the circle. Work out the gradient of the radius (CP) at the point the tangent meets the circle. Then use the equation m C P × m t g t = − 1 to find the gradient of the tangent.

Does a circle have a gradient?

Simply, the gradient of a circle at a given point on it is the slope of the tangent to the circle through that point.

What is radial gradient?

The radial-gradient() CSS function creates an image consisting of a progressive transition between two or more colors that radiate from an origin. Its shape may be a circle or an ellipse. The function's result is an object of the <gradient> data type, which is a special kind of <image> .

How to make radial gradient in css?

The radial-gradient() function sets a radial gradient as the background image. A radial gradient is defined by its center. To create a radial gradient you must define at least two color stops.


2 Answers

With some repeated use of clip, you can get there.

# set up a blank plot
par(mar=rep(0, 4))
par(bg="#cccccc")
plot(NA,xlim=0:1,ylim=0:1)

# define a function
grad.circ <- function(centrex,centrey,radius,col,resolution) {
  colfunc <- colorRampPalette(col)
  shades <- colfunc(resolution)

  for (i in seq_along(shades) ) {
   clip(
      centrex - radius,
      centrex + radius,
      (centrey + radius) - ((i-1) * (radius*2)/length(shades)),
      (centrey + radius) - (i     * (radius*2)/length(shades))
       )
   symbols(
     centrex,
     centrey,
     circles=radius,
     bg=shades[i],
     fg=NA,
     add=TRUE,
     inches=FALSE
          )
  }
}

# call the function
grad.circ(0.5,0.5,0.5,c("black", "white"),300)

Result:

enter image description here

EDIT (by Tyler Rinker):

I wanted to add the rest of the code I used to replicate the image:

FUN <- function(plot = TRUE, cols = c("black", "white")) {
    plot(NA, xlim=0:1, ylim=0:1, axes=FALSE)
    if (plot) {
        grad.circ(0.5, 0.5, 0.5, cols, 300)
    }
}

FUN2 <- function(){
    lapply(1:3, function(i) FUN(,c("white", "black")))
    FUN(F)
    lapply(1:3, function(i) FUN())
}


X11(10, 4.5)
par(mfrow=c(3, 7))
par(mar=rep(0, 4))
par(bg="gray70")
invisible(lapply(1:3, function(i) FUN2()))
like image 108
thelatemail Avatar answered Nov 07 '22 23:11

thelatemail


Here is a version using rasters and rasterImage:

image <- as.raster( matrix( seq(0,1,length.out=1001), nrow=1001, ncol=1001) )
tmp <- ( row(image) - 501 ) ^2 + ( col(image) - 501 )^2
image[tmp > 500^2] <- NA

image2 <- as.raster( matrix( seq(1,0, length.out=1001), nrow=1001, ncol=1001) )
image2[ tmp > 500^2 ] <- NA

image3 <- row(image) + col(image)
image3 <- image3/max(image3)
image3[tmp>500^2] <- NA
image4 <- 1-image3
image3 <- as.raster(image3)
image4 <- as.raster(image4)

plot( 0:1, 0:1, type='n', asp=1,ann=FALSE,axes=FALSE)
rect(0,0,1,1, col='grey')
rasterImage(image, 0.2, 0.2, 0.3, 0.3)
rasterImage(image2, 0.6, 0.6, 0.7, 0.7)
rasterImage(image3, 0.6, 0.3, 0.7, 0.4)
rasterImage(image4, 0.3, 0.7, 0.4, 0.8)

Other directions of shading can be made by changing the math a little.

like image 34
Greg Snow Avatar answered Nov 07 '22 22:11

Greg Snow