Home > Net >  How can I show proportional (0-1) bar charts alongside line data with very different axes?
How can I show proportional (0-1) bar charts alongside line data with very different axes?

Time:12-08

I have three lots of data I want to plot together: two geom_line() over the top of one stacked geom_bar(). All of that is over a time series, with a bar and two line values for each year. The data looks something like this:

df <- data.frame(year = rep(1:5, each = 3),
                 cat = c("small", "med", "large"),
                 count = rep(sample(1:10, 5)),
                 line1 = rep(sample(30000:40000, 5), each = 3),
                 line2 = rep(sample(200:300, 5), each = 3))

It's easy enough to plot all three together, but I don't want to show the y-axis label for the bars. Instead, I want the left axis to show one line and the right to show the other. I want the plot to look something like this:

like this

but to have the left axis show the line1 value (i.e. the 30000:40000 value). How would I go about including the two line axes, but still showing the bars across the whole height of the plot?

library(ggplot2)
ggplot(data = df, aes(x=year))  
  geom_bar(aes(y = count, x = year, fill = cat), position = "fill", stat="identity")  
  geom_line(aes(y = line1/max(line1)))  
  geom_line(aes(y = line2/max(line2)), color = "red")  
  scale_y_continuous(sec.axis = sec_axis(~.*max(df$line2), name = "line2 (red)"))

Simply adding the geom_bar() after a two-axis line plot results in the bars not showing, because the scale of the lines data is far beyond that of the proportional (0-1) bar data:

ggplot(data = df, aes(x=year))  
  geom_line(aes(y = line1))  
  geom_line(aes(y = line2*100), color = "red")  
  scale_y_continuous(sec.axis = sec_axis(~./100, name = "line2 (red)"))  
  geom_bar(aes(y = count, x = year, fill = cat), position = "fill", stat="identity")

I'd like these axes, but still show the bars:

CodePudding user response:

Could do it with dplyr calculations in line:

library(dplyr); library(ggplot2)
ggplot(data = df, aes(x=year))  
  geom_col(data = df %>% group_by(year) %>%
             mutate(share = count / sum(count) * max(df$line1)),
           aes(y = share, x = year, fill = cat))  
  geom_line(aes(y = line1))  
  geom_line(aes(y = line2*100), color = "red")  
  scale_y_continuous(sec.axis = sec_axis(~./100, name = "line2 (red)"))

enter image description here

  • Related