Home > OS >  How can I make the labels their own ggplot so that when I grid.arrange these 3 plots, the leftmost p
How can I make the labels their own ggplot so that when I grid.arrange these 3 plots, the leftmost p

Time:11-06

enter image description here

I have this plot I made with the code below. As you can see, the leftmost graph is made very narrow when I arrange these plots into a grid. I want them all to be equally wide, even if all three have to be more narrow to accommodate the row labels. I don't think this is quite the same as questions posted in the past because of the inclusion of relatively long, horizontal row labels.


p1<-ggplot(main.frame2, aes(x=item.true.prev, y=reorder(substring(Shorthand,5), item.true.prev), color=item.republican)) 
  geom_point(size=3) 
  theme_forest() 
    xlim(0,1)  xlab("True Prevalence") ylab("Item") 
  scale_colour_gradient(low="blue", high="red") 
    geom_stripes(odd = "#33333333", even = "#00000000") 
   tidytext::scale_y_reordered()  
    guides(color = "none")  
  theme(text = element_text(size=18))

p2<-ggplot(main.frame2, aes(x=perceived.prev, y=reorder(item.id.short, item.true.prev), color=item.republican)) 
  geom_point(size=3) 
  theme_forest() 
    xlim(0,1) xlab("Perceived Prevalence") ylab("") 
   scale_colour_gradient(low="blue", high="red") 
    geom_stripes(odd = "#33333333", even = "#00000000") 
   tidytext::scale_y_reordered()  
   theme(axis.text.y=element_blank()) 
  guides(color = "none")  
  
  theme(text = element_text(size=18))

p3<-ggplot(main.frame2, aes(x=generic.acceptance, y=reorder(item.id.short, item.true.prev), color=item.republican)) 
  geom_point(size=3) 
  theme_forest() 
    xlim(0,1) xlab("Generic Acceptance") ylab("") 
   scale_colour_gradient(low="blue", high="red") 
    geom_stripes(odd = "#33333333", even = "#00000000") 
   tidytext::scale_y_reordered()  
  guides(color = "none") 
     theme(axis.text.y=element_blank(),
        axis.ticks.y=element_blank()) 
  theme(text = element_text(size=18))


gridExtra::grid.arrange(p1,p2, p3, nrow=1)

And here is what the dataframe looks like:

   item.id.short Shorthand                    perceived.prev item.true.prev generic.acceptance
           <dbl> <chr>                                 <dbl>          <dbl>              <dbl>
 1            22 "(D) Liberal identity "              0.0755           0.07             0.0288
 2            42 "(R) Conservative identity "         0.0935           0.13             0.0336
 3            62 "(R) Prayer in schools"              0.132            0.18             0.0935
 4            40 "(R) Require Lord's Prayer"          0.139            0.42             0.0959
 5            28 "(D) Decrease police"                0.140            0.11             0.101 
 6            64 "(R) US as Christian nation"         0.141            0.06             0.0911
 7            52 "(R) Ban trans soldiers"             0.142            0.11             0.0671
 8            55 "(R) Withdraw Paris Deal"            0.154            0.11             0.0839
 9            56 "(R) Build southern wall"            0.154            0.13             0.0839
10            60 "(R) Eliminate gun permits"          0.156            0.17             0.0983

I have tried using a ggtextable() to create a fourth object for the grid.arrange, but that did not work. I just want the same width for all 3 plots.

CodePudding user response:

I don't know about gridExtra, but I know you could do it with the cowplot package.

cowplot::plot_grid(p1, p2, p3, nrow=1, rel_widths=c(1, .7, .7))

The exact values of relative widths you will have to figure out.

However, another solution comes to mind: you could use facet_wrap rather then combine the different plots. If you want any specifics, please post a minimal reproducible example.

Roughly, you would have to create a data frame with one column for the x variable and an additional column indicating whether it is true prevalence or something else. This you can easily achieve with pivot_longer, something like

main.frame2 %>% 
  pivot_longer(item.true.prevalence:generic_acceptance,
               names_to = "Response", values_to = "x")

Then you create one plot only, to which you add facet_wrap(~ Response) to your plot

CodePudding user response:

Using the widths in cowplot can be tricky. I find its easier to plot 3 without an axis and then plot just the axis.

library(tidyverse)
library(cowplot)

#example
p1 <- mtcars |>
  rownames_to_column("car") |>
  ggplot(aes(mpg,car)) 
  geom_point()

p2 <- p1 theme(axis.text.y = element_blank(),
               axis.title.y = element_blank(),
               axis.ticks.y = element_blank())
p3 <- p2

#problem
plot_grid(p1,p2,p3, nrow = 1)


#solution
blank_p <- mtcars |>
  rownames_to_column("car") |>
  ggplot(aes(y = car)) 
  geom_blank() 
  theme(panel.background = element_blank(),
        panel.border = element_blank())

p1 <- p1 theme(axis.text.y = element_blank(),
               axis.title.y = element_blank(),
               axis.ticks.y = element_blank())

plot_grid(blank_p, p1,p2,p3, nrow = 1, align = "h", axis = "tb",
          rel_widths = c(0.7, 1,1,1))

  • Related