Keeping plotted heights fixed when laying out a list ggplot together












2















I'm creating a list of ggplot heatmaps, which have the same number of rows but different number of columns and different lengths of their x-axis tick labels:



plot.list <- vector(mode="list",length(3))
n.cols <- c(600,30,300)
x.labs <- c("medium","this is a long label","sh")
library(ggplot2)

for(i in 1:3){
set.seed(1)
df <- reshape2::melt(matrix(rnorm(100*n.cols[i]),100,n.cols[i],dimnames = list(paste0("G",1:100),paste0("S",1:n.cols[i]))))
plot.list[[i]] <- ggplot(data=df,mapping=aes(x=Var2,y=Var1,fill=value))+
geom_tile()+theme_minimal()+scale_fill_gradient2(name="Scaled Value",low="darkblue",mid="gray",high="darkred")+
scale_x_discrete(name=NULL,breaks=unique(df$Var2)[floor(length(unique(df$Var2))/2)],labels=x.labs[i])+
scale_y_discrete(name=NULL)+
theme(legend.position=NULL,axis.title.x=element_blank(),axis.text.x=element_text(angle=90,hjust=1,vjust=0.5))
if(i != 1) plot.list[[i]] <- plot.list[[i]]+theme(axis.text.y=element_blank())
if(i != 3) plot.list[[i]] <- plot.list[[i]]+theme(legend.position = "none")
}


I then want to combine them together horizontally with a very small margin separating them, and have their widths be relative to the numbers of columns.



Trying to achieve this using gridExtra's arrangeGrob:



gridExtra::arrangeGrob(grobs=plot.list,ncol=length(plot.list),widths=n.cols,padding=0.01)


Or with cowplot's plot_grid:



cowplot::plot_grid(plotlist=plot.list,align="v",axis="tb",ncol=length(plot.list),rel_widths=n.cols)


Gives me:
enter image description here



So my questions are:




  1. How to get them to have the same height and have the x-axis labels extend downwards to varying lengths?

  2. Shrink the spaces between them? I tried reducing the padding value but see no change


Note that I know that using facet_grid might be the obvious way to create this in the first place, but I specifically need to first create the list of plots and only then combine them.










share|improve this question




















  • 1





    Check out cowplot::plot_grid() - this function has an align argument that lets you align plots by their axes. Package vignette here

    – Jan Boyer
    Nov 13 '18 at 20:21













  • Thanks for the suggestion @Jan Boyer. Tried it with what I think would be the right argument values and ended up getting exactly what gridExtra::arrangeGrob give me. I updated my post with that.

    – dan
    Nov 13 '18 at 21:09
















2















I'm creating a list of ggplot heatmaps, which have the same number of rows but different number of columns and different lengths of their x-axis tick labels:



plot.list <- vector(mode="list",length(3))
n.cols <- c(600,30,300)
x.labs <- c("medium","this is a long label","sh")
library(ggplot2)

for(i in 1:3){
set.seed(1)
df <- reshape2::melt(matrix(rnorm(100*n.cols[i]),100,n.cols[i],dimnames = list(paste0("G",1:100),paste0("S",1:n.cols[i]))))
plot.list[[i]] <- ggplot(data=df,mapping=aes(x=Var2,y=Var1,fill=value))+
geom_tile()+theme_minimal()+scale_fill_gradient2(name="Scaled Value",low="darkblue",mid="gray",high="darkred")+
scale_x_discrete(name=NULL,breaks=unique(df$Var2)[floor(length(unique(df$Var2))/2)],labels=x.labs[i])+
scale_y_discrete(name=NULL)+
theme(legend.position=NULL,axis.title.x=element_blank(),axis.text.x=element_text(angle=90,hjust=1,vjust=0.5))
if(i != 1) plot.list[[i]] <- plot.list[[i]]+theme(axis.text.y=element_blank())
if(i != 3) plot.list[[i]] <- plot.list[[i]]+theme(legend.position = "none")
}


I then want to combine them together horizontally with a very small margin separating them, and have their widths be relative to the numbers of columns.



Trying to achieve this using gridExtra's arrangeGrob:



gridExtra::arrangeGrob(grobs=plot.list,ncol=length(plot.list),widths=n.cols,padding=0.01)


Or with cowplot's plot_grid:



cowplot::plot_grid(plotlist=plot.list,align="v",axis="tb",ncol=length(plot.list),rel_widths=n.cols)


Gives me:
enter image description here



So my questions are:




  1. How to get them to have the same height and have the x-axis labels extend downwards to varying lengths?

  2. Shrink the spaces between them? I tried reducing the padding value but see no change


Note that I know that using facet_grid might be the obvious way to create this in the first place, but I specifically need to first create the list of plots and only then combine them.










share|improve this question




















  • 1





    Check out cowplot::plot_grid() - this function has an align argument that lets you align plots by their axes. Package vignette here

    – Jan Boyer
    Nov 13 '18 at 20:21













  • Thanks for the suggestion @Jan Boyer. Tried it with what I think would be the right argument values and ended up getting exactly what gridExtra::arrangeGrob give me. I updated my post with that.

    – dan
    Nov 13 '18 at 21:09














2












2








2








I'm creating a list of ggplot heatmaps, which have the same number of rows but different number of columns and different lengths of their x-axis tick labels:



plot.list <- vector(mode="list",length(3))
n.cols <- c(600,30,300)
x.labs <- c("medium","this is a long label","sh")
library(ggplot2)

for(i in 1:3){
set.seed(1)
df <- reshape2::melt(matrix(rnorm(100*n.cols[i]),100,n.cols[i],dimnames = list(paste0("G",1:100),paste0("S",1:n.cols[i]))))
plot.list[[i]] <- ggplot(data=df,mapping=aes(x=Var2,y=Var1,fill=value))+
geom_tile()+theme_minimal()+scale_fill_gradient2(name="Scaled Value",low="darkblue",mid="gray",high="darkred")+
scale_x_discrete(name=NULL,breaks=unique(df$Var2)[floor(length(unique(df$Var2))/2)],labels=x.labs[i])+
scale_y_discrete(name=NULL)+
theme(legend.position=NULL,axis.title.x=element_blank(),axis.text.x=element_text(angle=90,hjust=1,vjust=0.5))
if(i != 1) plot.list[[i]] <- plot.list[[i]]+theme(axis.text.y=element_blank())
if(i != 3) plot.list[[i]] <- plot.list[[i]]+theme(legend.position = "none")
}


I then want to combine them together horizontally with a very small margin separating them, and have their widths be relative to the numbers of columns.



Trying to achieve this using gridExtra's arrangeGrob:



gridExtra::arrangeGrob(grobs=plot.list,ncol=length(plot.list),widths=n.cols,padding=0.01)


Or with cowplot's plot_grid:



cowplot::plot_grid(plotlist=plot.list,align="v",axis="tb",ncol=length(plot.list),rel_widths=n.cols)


Gives me:
enter image description here



So my questions are:




  1. How to get them to have the same height and have the x-axis labels extend downwards to varying lengths?

  2. Shrink the spaces between them? I tried reducing the padding value but see no change


Note that I know that using facet_grid might be the obvious way to create this in the first place, but I specifically need to first create the list of plots and only then combine them.










share|improve this question
















I'm creating a list of ggplot heatmaps, which have the same number of rows but different number of columns and different lengths of their x-axis tick labels:



plot.list <- vector(mode="list",length(3))
n.cols <- c(600,30,300)
x.labs <- c("medium","this is a long label","sh")
library(ggplot2)

for(i in 1:3){
set.seed(1)
df <- reshape2::melt(matrix(rnorm(100*n.cols[i]),100,n.cols[i],dimnames = list(paste0("G",1:100),paste0("S",1:n.cols[i]))))
plot.list[[i]] <- ggplot(data=df,mapping=aes(x=Var2,y=Var1,fill=value))+
geom_tile()+theme_minimal()+scale_fill_gradient2(name="Scaled Value",low="darkblue",mid="gray",high="darkred")+
scale_x_discrete(name=NULL,breaks=unique(df$Var2)[floor(length(unique(df$Var2))/2)],labels=x.labs[i])+
scale_y_discrete(name=NULL)+
theme(legend.position=NULL,axis.title.x=element_blank(),axis.text.x=element_text(angle=90,hjust=1,vjust=0.5))
if(i != 1) plot.list[[i]] <- plot.list[[i]]+theme(axis.text.y=element_blank())
if(i != 3) plot.list[[i]] <- plot.list[[i]]+theme(legend.position = "none")
}


I then want to combine them together horizontally with a very small margin separating them, and have their widths be relative to the numbers of columns.



Trying to achieve this using gridExtra's arrangeGrob:



gridExtra::arrangeGrob(grobs=plot.list,ncol=length(plot.list),widths=n.cols,padding=0.01)


Or with cowplot's plot_grid:



cowplot::plot_grid(plotlist=plot.list,align="v",axis="tb",ncol=length(plot.list),rel_widths=n.cols)


Gives me:
enter image description here



So my questions are:




  1. How to get them to have the same height and have the x-axis labels extend downwards to varying lengths?

  2. Shrink the spaces between them? I tried reducing the padding value but see no change


Note that I know that using facet_grid might be the obvious way to create this in the first place, but I specifically need to first create the list of plots and only then combine them.







r ggplot2 grid gridextra grob






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 21:08







dan

















asked Nov 13 '18 at 20:03









dandan

1,50341046




1,50341046








  • 1





    Check out cowplot::plot_grid() - this function has an align argument that lets you align plots by their axes. Package vignette here

    – Jan Boyer
    Nov 13 '18 at 20:21













  • Thanks for the suggestion @Jan Boyer. Tried it with what I think would be the right argument values and ended up getting exactly what gridExtra::arrangeGrob give me. I updated my post with that.

    – dan
    Nov 13 '18 at 21:09














  • 1





    Check out cowplot::plot_grid() - this function has an align argument that lets you align plots by their axes. Package vignette here

    – Jan Boyer
    Nov 13 '18 at 20:21













  • Thanks for the suggestion @Jan Boyer. Tried it with what I think would be the right argument values and ended up getting exactly what gridExtra::arrangeGrob give me. I updated my post with that.

    – dan
    Nov 13 '18 at 21:09








1




1





Check out cowplot::plot_grid() - this function has an align argument that lets you align plots by their axes. Package vignette here

– Jan Boyer
Nov 13 '18 at 20:21







Check out cowplot::plot_grid() - this function has an align argument that lets you align plots by their axes. Package vignette here

– Jan Boyer
Nov 13 '18 at 20:21















Thanks for the suggestion @Jan Boyer. Tried it with what I think would be the right argument values and ended up getting exactly what gridExtra::arrangeGrob give me. I updated my post with that.

– dan
Nov 13 '18 at 21:09





Thanks for the suggestion @Jan Boyer. Tried it with what I think would be the right argument values and ended up getting exactly what gridExtra::arrangeGrob give me. I updated my post with that.

– dan
Nov 13 '18 at 21:09












1 Answer
1






active

oldest

votes


















3














Both egg:ggarrange and cowplot::plot_grid() can accomplish this.



As far as answering 1, try out:



library(egg)
plot1 <- plot.list[[1]]
plot2 <- plot.list[[2]]
plot3 <- plot.list[[3]]
ggarrange(plot1, plot2, plot3, ncol = 3, widths = c(600,30,300)) #originally had the 20,3,10, but I don't think it scales right.




As far as 2, you can set you plot.margins beforehand and arrange like before.



plot1 <- plot.list[[1]] + theme(plot.margin = margin(1,0,1,1)) # order is top, right, bottom, left. Go negative if you want them to touch.
plot2 <- plot.list[[2]] + theme(plot.margin = margin(1,0,1,0))
plot3 <- plot.list[[3]] + theme(plot.margin = margin(1,1,1,0))
ggarrange(plot1, plot2, plot3, ncol = 3, widths = c(600,30,300))


plot_grid will give you the same image as below.



cowplot::plot_grid(plot1, plot2, plot3, ncol = 3, axis = "b", align = "h", rel_widths = c(600,30,300))







share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53288653%2fkeeping-plotted-heights-fixed-when-laying-out-a-list-ggplot-together%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    Both egg:ggarrange and cowplot::plot_grid() can accomplish this.



    As far as answering 1, try out:



    library(egg)
    plot1 <- plot.list[[1]]
    plot2 <- plot.list[[2]]
    plot3 <- plot.list[[3]]
    ggarrange(plot1, plot2, plot3, ncol = 3, widths = c(600,30,300)) #originally had the 20,3,10, but I don't think it scales right.




    As far as 2, you can set you plot.margins beforehand and arrange like before.



    plot1 <- plot.list[[1]] + theme(plot.margin = margin(1,0,1,1)) # order is top, right, bottom, left. Go negative if you want them to touch.
    plot2 <- plot.list[[2]] + theme(plot.margin = margin(1,0,1,0))
    plot3 <- plot.list[[3]] + theme(plot.margin = margin(1,1,1,0))
    ggarrange(plot1, plot2, plot3, ncol = 3, widths = c(600,30,300))


    plot_grid will give you the same image as below.



    cowplot::plot_grid(plot1, plot2, plot3, ncol = 3, axis = "b", align = "h", rel_widths = c(600,30,300))







    share|improve this answer






























      3














      Both egg:ggarrange and cowplot::plot_grid() can accomplish this.



      As far as answering 1, try out:



      library(egg)
      plot1 <- plot.list[[1]]
      plot2 <- plot.list[[2]]
      plot3 <- plot.list[[3]]
      ggarrange(plot1, plot2, plot3, ncol = 3, widths = c(600,30,300)) #originally had the 20,3,10, but I don't think it scales right.




      As far as 2, you can set you plot.margins beforehand and arrange like before.



      plot1 <- plot.list[[1]] + theme(plot.margin = margin(1,0,1,1)) # order is top, right, bottom, left. Go negative if you want them to touch.
      plot2 <- plot.list[[2]] + theme(plot.margin = margin(1,0,1,0))
      plot3 <- plot.list[[3]] + theme(plot.margin = margin(1,1,1,0))
      ggarrange(plot1, plot2, plot3, ncol = 3, widths = c(600,30,300))


      plot_grid will give you the same image as below.



      cowplot::plot_grid(plot1, plot2, plot3, ncol = 3, axis = "b", align = "h", rel_widths = c(600,30,300))







      share|improve this answer




























        3












        3








        3







        Both egg:ggarrange and cowplot::plot_grid() can accomplish this.



        As far as answering 1, try out:



        library(egg)
        plot1 <- plot.list[[1]]
        plot2 <- plot.list[[2]]
        plot3 <- plot.list[[3]]
        ggarrange(plot1, plot2, plot3, ncol = 3, widths = c(600,30,300)) #originally had the 20,3,10, but I don't think it scales right.




        As far as 2, you can set you plot.margins beforehand and arrange like before.



        plot1 <- plot.list[[1]] + theme(plot.margin = margin(1,0,1,1)) # order is top, right, bottom, left. Go negative if you want them to touch.
        plot2 <- plot.list[[2]] + theme(plot.margin = margin(1,0,1,0))
        plot3 <- plot.list[[3]] + theme(plot.margin = margin(1,1,1,0))
        ggarrange(plot1, plot2, plot3, ncol = 3, widths = c(600,30,300))


        plot_grid will give you the same image as below.



        cowplot::plot_grid(plot1, plot2, plot3, ncol = 3, axis = "b", align = "h", rel_widths = c(600,30,300))







        share|improve this answer















        Both egg:ggarrange and cowplot::plot_grid() can accomplish this.



        As far as answering 1, try out:



        library(egg)
        plot1 <- plot.list[[1]]
        plot2 <- plot.list[[2]]
        plot3 <- plot.list[[3]]
        ggarrange(plot1, plot2, plot3, ncol = 3, widths = c(600,30,300)) #originally had the 20,3,10, but I don't think it scales right.




        As far as 2, you can set you plot.margins beforehand and arrange like before.



        plot1 <- plot.list[[1]] + theme(plot.margin = margin(1,0,1,1)) # order is top, right, bottom, left. Go negative if you want them to touch.
        plot2 <- plot.list[[2]] + theme(plot.margin = margin(1,0,1,0))
        plot3 <- plot.list[[3]] + theme(plot.margin = margin(1,1,1,0))
        ggarrange(plot1, plot2, plot3, ncol = 3, widths = c(600,30,300))


        plot_grid will give you the same image as below.



        cowplot::plot_grid(plot1, plot2, plot3, ncol = 3, axis = "b", align = "h", rel_widths = c(600,30,300))








        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 13 '18 at 21:28

























        answered Nov 13 '18 at 21:17









        Anonymous cowardAnonymous coward

        1,4531919




        1,4531919






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53288653%2fkeeping-plotted-heights-fixed-when-laying-out-a-list-ggplot-together%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Full-time equivalent

            Bicuculline

            さくらももこ