【问题标题】:ggplot: How to produce a gradient fill within a geom_polygonggplot:如何在 geom_polygon 中生成渐变填充
【发布时间】:2016-03-02 02:33:20
【问题描述】:

这应该很容易,但我找不到路。

tri_fill <- structure(
  list(x= c(0.75, 0.75, 2.25, 3.25), 
       y = c(40, 43, 43, 40)), 
  .Names = c("x", "y"),
  row.names = c(NA, -4L), class = "data.frame",Integrated=NA, Related=NA)

# install.packages("ggplot2", dependencies = TRUE)
require(ggplot2)


  ggplot(data=tri_fill,aes(x=x, y=y))+ 
      geom_polygon() + 
      scale_fill_gradient(limits=c(1, 4), low = "lightgrey", high = "red")

我想要的是沿 x 轴的渐变,但上面我只得到一个带有渐变的图例和带有实心填充的多边形。

【问题讨论】:

  • 这不是小事,因为多边形只有一种填充颜色。你想要的多边形到底是这个“简单”,还是形状更复杂?

标签: r ggplot2 polygon gradient


【解决方案1】:

in this question 找到的关于热映射三角形的答案达到了相同的效果,并且可以用于任何复杂的多边形形状。

【讨论】:

    【解决方案2】:

    当您有一个相对简单的多边形时,这是一个可能的解决方案。我们创建了许多线段并通过渐变对它们进行着色,而不是多边形。因此,结果将看起来像一个带有渐变的多边形。

    #create data for 'n'segments
    n_segs <- 1000
    
    #x and xend are sequences spanning the entire range of 'x' present in the data
    newpolydata <- data.frame(xstart=seq(min(tri_fill$x),max(tri_fill$x),length.out=n_segs))
    newpolydata$xend <- newpolydata$xstart
    
    
    #y's are a little more complicated: when x is below changepoint, y equals max(y)
    #but when x is above the changepoint, the border of the polygon
    #follow a line according to the formula y= intercept + x*slope.
    
    #identify changepoint (very data/shape dependent)
    change_point <-  max(tri_fill$x[which(tri_fill$y==max(tri_fill$y))])
    
    #calculate slope and intercept
    slope <- (max(tri_fill$y)-min(tri_fill$y))/ (change_point - max(tri_fill$x))
    intercept <- max(tri_fill$y)
    
    #all lines start at same y
    newpolydata$ystart <- min(tri_fill$y)
    
    #calculate y-end
    newpolydata$yend <- with(newpolydata, ifelse (xstart <= change_point,
                          max(tri_fill$y),intercept+ (xstart-change_point)*slope))
    
    p2 <- ggplot(newpolydata) +
      geom_segment(aes(x=xstart,xend=xend,y=ystart,yend=yend,color=xstart)) +
      scale_color_gradient(limits=c(0.75, 4), low = "lightgrey", high = "red")
    p2 #note that I've changed the lower border of the gradient.
    

    编辑:如果一个人只需要一个具有渐变的多边形,则上述解决方案有效,但是,正如 cmets 中所指出的,当您计划映射一个要填充的东西和另一个要着色的东西时,这可能会出现问题,因为每个 ' aes' 只能使用一次。因此,我将解决方案修改为不绘制线,而是绘制(非常细的)可以具有填充 aes 的多边形。

    #for each 'id'/polygon, four x-variables and four y-variable
    #for each polygon, we start at lower left corner, and go to upper left, upper right and then to lower right.
    
    
    n_polys <- 1000
    #identify changepoint (very data/shape dependent)
    change_point <-  max(tri_fill$x[which(tri_fill$y==max(tri_fill$y))])
    
    #calculate slope and intercept
    slope <- (max(tri_fill$y)-min(tri_fill$y))/ (change_point - max(tri_fill$x))
    intercept <- max(tri_fill$y)
    #calculate sequence of borders: x, and accompanying lower and upper y coordinates
    x_seq <- seq(min(tri_fill$x),max(tri_fill$x),length.out=n_polys+1)
    y_max_seq <- ifelse(x_seq<=change_point, max(tri_fill$y), intercept + (x_seq - change_point)*slope)
    y_min_seq <- rep(min(tri_fill$y), n_polys+1)
    
    #create polygons/rectangles
    poly_list <- lapply(1:n_polys, function(p){
      res <- data.frame(x=rep(c(x_seq[p],x_seq[p+1]),each=2),
                        y = c(y_min_seq[p], y_max_seq[p:(p+1)], y_min_seq[p+1]))
      res$fill_id <- x_seq[p]
      res
    }
    )
    
    poly_data <- do.call(rbind, poly_list)
    
    #plot, allowing for both fill and color-aes
    p3 <- ggplot(tri_fill, aes(x=x,y=y))+
      geom_polygon(data=poly_data, aes(x=x,y=y, group=fill_id,fill=fill_id)) +
      scale_fill_gradient(limits=c(0.75, 4), low = "lightgrey", high = "red") +
      geom_point(aes(color=factor(y)),size=5)
    p3
    

    【讨论】:

    • 谢谢,希罗卡。我可以重现你的渐变。然而,这应该放在另一个情节(有更多的几何和比例)之上,这使得它有点复杂......
    • 你能更新你的例子吗?为什么它不能放在其他东西之上?
    • 把它画在别的东西下可能会更好,想想吧。
    • @Almstrup 我意识到你不能组合不同的颜色-aes。将解决方案从线条更改为非常细的多边形,并表明它可以与颜色组合。希望对您有所帮助。
    • 是的,这是有效的。谢谢!然而,它应该以某种方式实现它作为 geom_polygon 的内置解决方案......
    猜你喜欢
    • 1970-01-01
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多