MLEN
MLEN

Reputation: 2561

Creating a facet theme/design plot in ggplot2 without using facet_

Is there any possibility to create a facet_wrap looking plot in ggplot2 without using facet_wrap() The reason I would like to achieve this is to match some other design. In the plot without_facet below, can I somehow add "Setosa" in the top, so it looks like the with_facet plot, without using facet_wrap.

library(ggplot2)

df <- iris[iris$Species == 'setosa', ]

with_facet <- ggplot(df, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point() +facet_wrap(~Species)
with_facet

without_facet <- ggplot(df, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point()

Upvotes: 0

Views: 798

Answers (4)

MLEN
MLEN

Reputation: 2561

From Paleolimbot answer on Gitbub (https://github.com/tidyverse/ggplot2/issues/2344)

element_textbox <- function(...) {
  el <- element_text(...)
  class(el) <- c("element_textbox", class(el))
  el
}

element_grob.element_textbox <- function(element, ...) {
  text_grob <- NextMethod()
  rect_grob <- element_grob(calc_element("strip.background", theme_bw()))

  ggplot2:::absoluteGrob(
    grid::gList(
      element_grob(calc_element("strip.background", theme_bw())),
      text_grob
    ),
    height = grid::grobHeight(text_grob), 
    width = grid::unit(1, "npc")
  )
}

From my original question, I added theme_bw()

library(ggplot2)
library(gridExtra)

df <- iris[iris$Species == 'setosa', ]

with_facet <- ggplot(df, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point() +
  facet_wrap(~Species) + 
  theme(plot.background = element_rect(color = 'black')) + theme_bw()

without_facet <- ggplot(df, aes(x = Sepal.Length, y = Sepal.Width)) + 
  geom_point() + 
  ggtitle("setosa")  + 
  theme_bw() +
  theme(
    plot.title = element_textbox(
      hjust = 0.5, margin = margin(t = 5, b = 5), size = 10
    ),
  )

grid.arrange(with_facet, without_facet)

enter image description here

Not identical, but works for my purpose.

Upvotes: 1

Roman
Roman

Reputation: 17648

You can try

ggplot(df, aes(x = Sepal.Length, y = Sepal.Width)) + 
   geom_point() + 
   ggtitle("setosa")  + 
   theme(plot.title = element_text(hjust = 0.5))

enter image description here

A more "hackish"-one could be this hardcoded approach:

ggplot(df, aes(x = Sepal.Length, y = Sepal.Width)) + 
  geom_point() + 
  ggtitle("setosa")  + 
  geom_rect(xmin = 4.225, xmax = 5.875 , ymin=4.5, ymax=4.6, fill ="lightgrey") + 
  coord_cartesian(clip = 'off', expand = 0.05) +
  theme(plot.title = element_text(hjust = 0.5, size = 12),
        plot.margin = margin(t = 30, r = 20, b = 20, l = 20, unit = "pt"))

enter image description here

Upvotes: 2

desval
desval

Reputation: 2435

Note: I had deleted it because it seemed no longer relevant after the original question was updated.

I am not sure I understand correctly. In case you want to arrange different plots together:

library(gridExtra)

grid.arrange(without_facet,
             without_facet,
             without_facet,
             without_facet, nrow = 2)

enter image description here

Upvotes: 0

Peter
Peter

Reputation: 12719

This might be one option:


library(ggplot2)

df <- iris[iris$Species == 'setosa', ]

# with annotate:


with_annotate <-
  ggplot(df, aes(x = Sepal.Length, y = Sepal.Width)) + 
  geom_point() +
  annotate('text', x = 5, y = 4.7, label = "setosa", size = 12)

with_annotate

#or if you do not want the heading to print over the plot area

with_coord_cart <-
  ggplot(df, aes(x = Sepal.Length, y = Sepal.Width)) + 
  geom_point() +
  annotate('text', x = 5, y = 4.7, label = "setosa", size = 8)+
  coord_cartesian(ylim = c(2, 4.5), clip = 'off') +
  theme(plot.margin = margin(2, 1, 1, 1, "lines"))


with_coord_cart


Which gives you:

enter image description here

Upvotes: 0

Related Questions