1
votes

I want to plot a 100% stacked area chart out of a dataframe, where each row of the df sums up to 1. An example dataframe is here: https://pastebin.com/ADMQP6Nx

What i want ultimately is something like this: enter image description here

Most solutions i found so far here on SO have a different data.frame structure, where the grouping variables are defined in rows rather than as columns, e.g.:

+--------+-------+-------+
| Period | Group | Value |
+--------+-------+-------+
| 1      | t1    | 0.3   |
| 1      | t2    | 0.1   |
| 1      | t3    | 0.4   |
| 1      | t4    | 0.2   |
| 2      | t1    | 0.5   |
| 2      | t2    | 0.1   |
| 2      | t3    | 0.3   |
| 2      | t4    | 0.2   |
| ...    | ...   | ...   |
+--------+-------+-------+

And they use then ggplot like this:

ggplot(data, aes(x=Period, y=Value, fill=Group)) +  geom_area()

Is there a solution without transforming the data frame?

1
"I don't want to transform my data frame." Why? This is objectively the best way to do it. - Jack Brookes
Ok maybe i should paraphrase it: Is there a solution without transforming the data frame? Anyways, any solution that works is appreciated. I am just afraid that the transforming would cost performance, because the original data frames have more than 400.000 elements. - UDE_Student
Not an easy one... ggplot is built to work with long data. But transforming your data is very easy. If you share data reproducibly in the question with dput() I'll be happy to help out. - Gregor Thomas
Maybe there's a weird hack, but ggplot is an implementation of the "grammar of graphics", which lends itself to "long" format - Jack Brookes
Ok, how would a solution with transforming the data frame look like? - UDE_Student

1 Answers

6
votes

Transforming the data with gather:

library(tidyverse)

df <- structure(
  list(
    Period = 1:4,
    t1 = c(0.3, 0.5, 0.1, 0.4),
    t2 = c(0.1, 0.1, 0.3,
           0.2),
    t3 = c(0.4, 0.2, 0.4, 0.3),
    t4 = c(0.2, 0.2, 0.2, 0.1)
  ),
  .Names = c("Period", "t1",
             "t2", "t3", "t4"),
  row.names = c(NA, -4L),
  class = "data.frame"
)


df %>% 
  gather(Group, Value, t1:t4) %>% 
  ggplot(aes(x=Period, y=Value, fill=Group)) + 
  geom_area()

enter image description here