Reputation: 604
I'm working on recreating the look of a plot found in a recent Economist article. There are two bar graphs connected by lines with the space in between them having the same color, albeit a little opaque.
I've seen this question asked but the examples only have lines connecting the bar graphs. Here's some fake data:
set.seed(0)
data_bar <- data.frame(
stringsAsFactors = F,
Sample = rep(c("A", "B"), each = 10),
Percentage = runif(20),
Taxon = rep(1:10, by = 2)
)
I've worked on reworking the linked example with no success. Any ideas?
Also in case you can't see the graph here's a screen shot:
Upvotes: 2
Views: 2598
Reputation: 23757
This is essentially an alluvial chart, and you can use the ggalluvial package for this.
You will need to use geom_flow
, as it creates the geom "in between" the bars (use geom_col for those), and you need to set curve_type = "linear"
.
library(ggalluvial)
#> Loading required package: ggplot2
library(tidyverse)
set.seed(0)
data_bar <- data.frame(
stringsAsFactors = F,
Sample = rep(c("A", "B"), each = 10),
Percentage = runif(20),
Taxon = rep(1:10, by = 2)
)
## first need to calcualte the actual percentage by group
data_bar %>%
group_by(Sample) %>%
mutate(perc = Percentage* 100/sum(Percentage)) %>%
ggplot(aes(y = perc, x = Sample, fill = as.character(Taxon))) +
geom_flow(aes(alluvium = Taxon), alpha= .5, color = "white",
curve_type = "linear",
width = .5) +
geom_col(width = .5, color = "white") +
scale_fill_brewer(palette = "RdBu")+
scale_y_continuous(NULL, expand = c(0,0)) +
cowplot::theme_minimal_hgrid() +
theme(panel.grid.major = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank())
#> Warning: The `.dots` argument of `group_by()` is deprecated as of dplyr 1.0.0.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
Created on 2022-01-25 by the reprex package (v2.0.1)
Upvotes: 2
Reputation: 37953
This took some fiddling adjusting the width of the bars and the x-position of the area, but essentially geom_area(..., position = "fill")
could take you pretty far. Alternatively you could also use position = "stack"
.
library(ggplot2)
set.seed(0)
data_bar <- data.frame(
stringsAsFactors = F,
Sample = rep(c("A", "B"), each = 10),
Percentage = runif(20),
Taxon = rep(1:10, by = 2)
)
ggplot(data_bar, aes(Sample, Percentage, fill = Taxon, group = Taxon)) +
geom_col(position = "fill", width = 0.5, colour = "black") +
geom_area(aes(x = c("A" = 1.25, "B" = 1.75)[Sample]),
position = "fill", colour = "black", alpha = 0.5,
outline.type = "both")
Created on 2021-02-16 by the reprex package (v1.0.0)
Alternative with stacking:
ggplot(data_bar, aes(Sample, Percentage, fill = Taxon, group = Taxon)) +
geom_col(position = "stack", width = 0.5, colour = "black") +
geom_area(aes(x = c("A" = 1.25, "B" = 1.75)[Sample]),
position = "stack", colour = "black", alpha = 0.5,
outline.type = "both")
Upvotes: 4