Reputation: 1
I have a 100% stacked bar chart with variable width bars, but I would like for there to be no space gaps between the bars or overlap between the bars. Here is my sample data and output without the scale_x_continuous line.
library(ggplot2)
df <- data.frame(x = c("A","A","B","B","C","C"), group = c("L","R","L","R","L","R"),width = c(0.1,0.1,0.50,0.50,0.40,0.40), y = c(0.75,0.25,0.5,0.5,0.9,0.1))
pos <- 0.5 * (cumsum(df$width) + cumsum(c(0, df$width[-length(df$width)])))
g <-ggplot(df, aes(x = x, y = y, width = width*2, fill = group)) +
geom_bar(stat = "identity", color = "white" ) +
scale_x_continuous(breaks = pos)
g
I have referenced the following threads and wasn't able to get the solutions to work for my scenario:
How to make variable bar widths in ggplot2 not overlap or gap
Spineplots in ggplot or at least vertical labels
The 1st link isnt using a stacked chart, but solves for the gap issue on a standard bar chart. The 2nd link is exactly what I am looking for, but I cant recreate the solution with my sample data. Am I missing something obvious?
Upvotes: 0
Views: 213
Reputation: 1067
The margin space over and around plots is controlled by the expansion
argument of the scale_y_x()
functions (in your case, scale_y_continuous
and scale_x_discrete
). It's called expansion because it's a multiplicative factor that adds space on top and below the bars, so setting the expansion to 0 will remove any extra space around your plot. Therefore, you can remove this expansion margin like this:
library(ggplot2)
df <- data.frame(x = c("A","A","B","B","C","C"), group = c("L","R","L","R","L","R"),width = c(0.1,0.1,0.50,0.50,0.40,0.40), y = c(0.75,0.25,0.5,0.5,0.9,0.1))
pos <- 0.5 * (cumsum(df$width) + cumsum(c(0, df$width[-length(df$width)])))
ggplot(df, aes(x = x, y = y, width = width*2, fill = group)) +
geom_bar(stat = "identity", color = "white") +
scale_y_continuous(expand = expansion(0)) +
scale_x_discrete(expand = expansion(0))
EDIT: To get the bars to touch each other, i.e., to plot bars that have no horizontal space between them, we can calculate their position on the x axis as follows:
library(dplyr)
library(ggplot2)
df <- data.frame(x = c("A","A","B","B","C","C"), group = c("L","R","L","R","L","R"),width = c(0.1,0.1,0.50,0.50,0.40,0.40), y = c(0.75,0.25,0.5,0.5,0.9,0.1))
df2 <- df |>
mutate(id = as.factor(x) |> as.numeric()) |>
mutate(x2 = id * (2-width))
ggplot(df2, aes(x = x2, y = y, width = width*4, fill = group)) +
geom_bar(stat = "identity", color = "white") +
scale_y_continuous(expand = expansion(0)) +
scale_x_continuous(labels = df2$x, breaks = df2$x2, expand = expansion(0))
Upvotes: 0