Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate a Filled geom_step

Tags:

r

ggplot2

I can get a "filled" geom_line with either geom_ribbon or geom_area. Is there an equivalent for geom_step that doesn't require messing with polygons/barplots or creating the actual step points? Here is some sample data:

library(ggplot2)
set.seed(1)
df <- data.frame(
  x=rep(sort(sample(1:20, 5)), 3), 
  y=ave(runif(15), rep(1:3, each=5), FUN=cumsum),
  grp=letters[rep(1:3, each=5)]
)
ggplot(df, aes(x=x, y=y, color=grp)) + geom_step(position="stack")

Which produces:

enter image description here

Basically, I want exactly the same thing, but with filled areas. I know how to do this by actually creating the x/y values required for the steps and using geom_area, but I'm hoping there is something simpler.

like image 713
BrodieG Avatar asked Feb 19 '14 16:02

BrodieG


2 Answers

Here is the answer I was thinking of, for reference, but I'm hoping for something simpler/built-in if possible:

df2 <- rbind(
  df,
  transform(df[order(df$x),],
    x=x - 1e-9,  # required to avoid crazy steps
    y=ave(y, grp, FUN=function(z) c(z[[1]], head(z, -1L)))
) )
ggplot(df2, aes(x=x, y=y, fill=grp)) + geom_area()

enter image description here

like image 182
BrodieG Avatar answered Oct 02 '22 23:10

BrodieG


I know the question is a few years old, but I had the same problem today. For reference here's my solution. It's not more concise than the original answer, but may be easier to understand for some.

library(ggplot2)
library(dplyr)

df <- data.frame(x = seq(10), y = sample(10))

df_areaStep <- bind_rows(old = df, 
                         new = df %>% mutate(y = lag(y)),
                         .id = "source") %>%
               arrange(x, source)

ggplot(df, aes(x,y)) + 
  geom_ribbon(aes(x = x, ymin = 0, ymax = y), data = df_areaStep)

See this gist for longer version with comments.

like image 26
Tobias Hotzenplotz Avatar answered Oct 02 '22 23:10

Tobias Hotzenplotz