n3lmnTrxx
n3lmnTrxx

Reputation: 416

Adding horizontal title/label to bar charts in ggplot R

is there a way to plot a bar graph in ggplot and group the bars accordingly using a horizontal line with label. It should look something like in the image below but for multiple groups and bars in one single graph only.

For context, I'm planning to group three bars for each horizontal label in one graph. For example, the first 3 bars would represent my control, the next three bars would be for treatment 1, the next three would be for treatment 2, and so on.

Let me know if you have a template for making such a graph. Thanks!

enter image description here

Upvotes: 0

Views: 154

Answers (2)

stefan
stefan

Reputation: 125832

The default approach to achieve the kind of grouping would be via faceting, However, TBMK the default element_rect provided by ggplot2 does not offer the option to just draw a top line.

One option would be to create a custom theme element to achieve that. To this end I adapted the code for the default element_rect where I replaced the rectGrob by a linesGrob.

Moreover, to also add the top lines for the axis labels I draw on ggh4x to add the axis labels via facets too. Doing so allows to use the custom theme element to add the top lines for the "axis labels" too (Of course would it be possible to create another custom theme element.).

Using mtcars as example data:

element_rect2 <- function(colour = NULL, size = NULL, linetype = NULL,
                          color = NULL, inherit.blank = FALSE) {
  if (!is.null(color)) {
    colour <- color
  }
  structure(list(
    colour = colour, size = size,
    linetype = linetype, inherit.blank = inherit.blank
  ),
  class = c("element_rect2", "element_rect", "element")
  )
}

element_grob.element_rect2 <- function(element, x = unit(c(0, 1), "npc"), y = unit(c(1, 1), "npc"),
                                       colour = NULL, size = NULL, linetype = NULL, ...) {
  gp <- grid::gpar(lwd = size, col = colour, lty = linetype)
  element_gp <- grid::gpar(lwd = element$size, col = element$colour, lty = element$linetype)
  gp <- modifyList(element_gp, gp)
  grid::linesGrob(x, y - unit(gp$lwd, unit = "pt"), gp = gp, ...)
}

library(ggplot2)
library(ggh4x)

ggplot(mtcars, aes(factor(cyl))) +
  geom_bar() +
  scale_y_continuous(expand = expansion(mult = c(0, .05))) +
  labs(x = NULL, y = NULL) +
  facet_wrap2(am ~ cyl,
    strip.position = "bottom", scales = "free_x",
    strip = strip_nested(
      background_x = list(
        element_rect2(size = 2),
        element_rect2(size = 2)
      ),
      by_layer_x = TRUE
    ),
    nrow = 1
  ) +
  theme_minimal() +
  theme(
    panel.grid = element_blank(),
    axis.line.y = element_line(size = .75, lineend = "square"),
    axis.ticks.y = element_line(size = .75),
    axis.text.x = element_blank(),
    strip.placement = "outside"
  )

Upvotes: 2

jrcalabrese
jrcalabrese

Reputation: 2321

You can use geom_bar() from the ggplot2 package to make similar looking bar plots.

library(ggplot2)
data(iris)
ggplot(iris, aes(x = Species, y = Petal.Length)) + 
  geom_bar(stat = "identity", fill = "black") +
  theme_bw()

enter image description here

Upvotes: 0

Related Questions