2015-11-27 15 views
5

içinde bir degrade dolgusu nasıl üretilir? Bu oldukça kolay olmalı ama yolumu bulamıyorum.ggplot: Bir geom_polygon

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") 

İstediğim x ekseni boyunca bir degrade olduğunu, ancak yukarıdaki ile sadece bir gradyan ve katı dolgulu çokgen içeren bir açıklama olsun.

plot

+0

Bu önemsiz bir konu değildir. Sonunda istediğiniz çokgen bu 'basit' mi, yoksa daha karmaşık mı? – Heroka

cevap

5

Burada nispeten basit çokgen varken için olası bir çözümdür. Çokgen yerine çok sayıda çizgi parçası oluştururuz ve bunları bir degrade ile renklendiririz. Sonuç böylece bir degrade olan bir çokgen gibi görünecektir.

#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. 

enter image description here

DÜZENLEME: Açıklamalarda belirttiği edildi bu doldurmak için bir şey eşlemek planladıklarını zaman sorunlar ortaya çıkabilir gibi bir durum ancak, bir dereceyle bir çokgen isterse çözüm çalışır yukarıda ve her bir 'aes' sadece bir kez kullanılabilecek şekilde renklendirilecek başka bir şey. Bu nedenle, çizgileri çizmemek için çözümü değiştirdim, ancak doldurma aeslerine sahip olan çok ince çokgenler çizdim. çokgenler tek dolgu rengi olduğu gibi

#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 

enter image description here

+0

Teşekkürler, Heroka. Gradyanınızı çoğaltabilirim. Ancak, bu biraz karmaşık hale getirir başka bir arsa (daha fazla geoms ve ölçekler ile) üstüne gitmeli .... – Almstrup

+0

Örneğini güncelleyebilir miyim? Neden başka bir şeyin üstüne çıkamaz? – Heroka

+0

Başka bir şeyin altında çizmek daha iyi olabilir, düşünün. – Heroka