Problem in defining the y-axis limit for the stacked bar plot when using ggplot2 package

27 Views Asked by At

I tried to create a "stacked bar plot" using ggplot2. The code as follow

plot_data <- data.frame(
State = rep(c("All India", "Arunachal Pradesh", "Gujarat", "Jammu & Kashmir", "Madhya Pradesh",
"Maharashtra", "Meghalaya", "Mizoram", "Orissa", "Punjab", "Tamil Nadu",
"Uttar Pradesh", "West Bengal"), each = 3),

Metric = factor(rep(c("5th Percentile", "Mean", "95th Percentile"), times = 13),
levels = c("95th Percentile", "Mean", "5th Percentile")),

Value = c(163, 217, 271, 193, 227, 262, 162, 214, 265, 185, 217, 249,
177, 217, 258, 146, 204, 261, 169, 209, 249, 173, 215, 257,
167, 223, 280, 183, 243, 302, 156, 220, 284, 163, 230, 297,
170, 210, 249)
)

library(ggplot2)

# Increase the size of the plot
options(repr.plot.width=10, repr.plot.height=6) # Adjust width and height as needed

ggplot(plot_data, aes(x = State, y = Value, fill = Metric)) +
  geom_bar(stat = "identity") + 
  geom_text(aes(label = Value), position = position_stack(vjust = 0.5)) + 
  scale_fill_manual(values = c("5th Percentile" = "green", "Mean" = "pink", "95th Percentile" = "orange")) +
  labs(title = " ",
       x = "State",
       y = "ABDOMINAL DEPTH SITTING",
       fill = " ") +  theme_light() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1, size = 14, face = "bold"),
        axis.text.y = element_text(size = 12, face = "bold"),
        axis.title.x = element_text(size = 18, face = "bold"),
        axis.title.y = element_text(size = 15, face = "bold"), legend.position = "top",
        legend.text = element_text(size = 15, face = "bold"))    

The above code create a plot as follow The output Plot of above code

The Y-axis is not aligning with bar, hence I used different methos

scale_y_continuous(limits = c(100, 350))
ylim(100, 350)

But after using the scale_y_continuous(limits = c(100, 350)) or ylim(100, 350), the bar is changed compltly and it is getting distorted. example Distorted plot after using scale_y_continuous(limits = c(100, 350))

I tried different scale_y_continuous(limits = c(100, 350)) and ylim(100, 350), but it is not working.

What i need is the provision to apply y-axis limits but it should not disturb the actuall plot. Kindly HELP me.

1

There are 1 best solutions below

0
stefan On

Using the ylim or the limits= will not work. After a second look at the image of your desired plot in your former post I think I finally understood what you are trying to achieve. The issue is that you don't want to make a stacked bar plot of the values in your dataset. Instead you want a stacked barplot of the "differences":

library(ggplot2)
library(dplyr, warn = FALSE)
library(tidyr)

plot_data <- plot_data |>
  arrange(desc(Metric)) |>
  mutate(
    value_bar = Value - lag(Value, default = 0),
    .by = State
  ) |>
  arrange(State)

plot_fun <- function(state) {
  plot_data |>
    subset(
      State %in% c("All India", state)
    ) |>
    ggplot(aes(x = State, y = value_bar, fill = Metric)) +
    geom_col(
      color = "white",
      linewidth = .25,
      width = .75
    ) +
    geom_text(aes(label = Value),
      position = position_stack(vjust = 0.5)
    ) +
    scale_fill_manual(
      values = c(
        "5th Percentile" = "orange",
        "Mean" = "blue",
        "95th Percentile" = "forestgreen"
      )
    ) +
    scale_y_continuous(
      expand = c(0, 0, .05, 0),
      limits = \(x) {
        c(0, range(scales::breaks_extended(only.loose = TRUE)(x))[2])
      }
    ) +
    labs(
      title = paste0(
        "Stacked Bar Plot for All India and ",
        state
      ),
      x = "State",
      y = "Values",
      fill = "Metric"
    ) +
    theme_bw() +
    theme(
      panel.grid = element_blank()
    )
}

lapply(unique(plot_data$State)[-1][1:2], plot_fun)
#> [[1]]

#> 
#> [[2]]