Centering a plot

705 views
Skip to first unread message

David Kaplan

unread,
Jan 2, 2022, 10:08:06 AM1/2/22
to ggplot2
Greetings all,

Below you'll see a series of plots.  I would like the last plot to be centered below the plots in the second row but of the same height and width.  

ShrinkagePlots.jpeg


Here is the code

llibrary(tidyverse)
library(LaplacesDemon)
library(VGAM)  # For laplace distribution
library(patchwork) # For plot layouts


ridge=ggplot(data.frame(x = c(-10, 10)), aes(x = x)) + theme_bw()+
  theme(panel.grid.major=element_blank())+theme(panel.grid.minor=element_blank()) +
  labs(x=expression(theta),y=expression(p(theta)))+
  stat_function(fun=dnorm, args=list(mean=0, sd=1))

laplace= ggplot(data.frame(x = c(-20, 20)), aes(x = x)) +theme_bw()+
  theme(panel.grid.major=element_blank())+theme(panel.grid.minor=element_blank()) +
  labs(x=expression(theta),y=expression(p(theta)))+
  stat_function(fun=dlaplace, args=list(location=0, scale=4))

horseshoe <- ggplot(data.frame(x = c(-8, 8)), aes(x = x))+theme_bw()+
  theme(panel.grid.major=element_blank())+theme(panel.grid.minor=element_blank()) +
 labs(x=expression(theta),y=expression(p(theta)))+stat_function(fun=dhs, args=list(lambda=dhalfcauchy(0,1), tau=dhalfcauchy(0,1)))

###### Finish Horseshoe
c2 = dinvgamma(.5,.5)
lambda = dhalfcauchy(0,1)
lambda2 = lambda^2
tau=dhalfcauchy(0,1)
tau2 = tau^2
lambda2_tilda = lambda_tilda2 = c2*lambda2/(c2+tau2*lambda2)

FinnHorseshoe <- ggplot(data.frame(x = c(-8, 8)), aes(x = x))+theme_bw()+
  theme(panel.grid.major=element_blank())+theme(panel.grid.minor=element_blank()) +
  labs(x=expression(theta),y=expression(p(theta)))+
  stat_function(fun=dhs, args=list(lambda=lambda2_tilda, tau=tau))
########

spikeSlab <- ggplot(data.frame(x = c(-1.5, 1.5)), aes(x = x))+theme_bw()+ylim(0,1)+
theme(panel.grid.major=element_blank())+theme(panel.grid.minor=element_blank()) +
geom_vline(xintercept=0,color = 'black',linetype = 'solid',size = 1) +
labs(x=expression(theta),y=expression(p(theta)))+stat_function(fun = dnorm,args=list(mean=0,sd=3))

((ridge | laplace) / (horseshoe | FinnHorseshoe) / spikeSlab)


Thank you!

David






Brandon Hurr

unread,
Jan 2, 2022, 12:45:31 PM1/2/22
to David Kaplan, ggplot2
Closest I can get is the following: 
layout <-
"
AABB
CCDD
#EE#
"
ridge + laplace + horseshoe + FinnHorseshoe + spikeSlab + plot_layout(design = layout)

Screen Shot 2022-01-02 at 12.43.40 PM.png
But it's not quite right. A, C and E are the same width, but B and D look narrow. I'm not sure what the issue is since this should work. 

--
--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: https://github.com/hadley/devtools/wiki/Reproducibility
 
To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com
More options: http://groups.google.com/group/ggplot2

---
You received this message because you are subscribed to the Google Groups "ggplot2" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ggplot2+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ggplot2/5c0085b0-79ce-434a-aced-608735fd267en%40googlegroups.com.

David Kaplan

unread,
Jan 3, 2022, 7:03:56 AM1/3/22
to ggplot2
Actually, I found that this works, though I would like to make the bottom plot in the same width and height as the others.

(ridge | laplace) /
(horseshoe | FinnHorseshoe) /
(plot_spacer() | spikeSlab | plot_spacer())

David Kaplan

unread,
Jan 3, 2022, 7:03:59 AM1/3/22
to Brandon Hurr, ggplot2
Hi Brandon,

Thanks.  Yea, I'm getting the same thing.  Perhaps someone in gg-land can explain that problem.

David

David Kaplan

unread,
Jan 3, 2022, 4:01:05 PM1/3/22
to Avi Gross, ggplot2
Thanks Avi,

Centering the last plot is no longer the problem.  My later post shows that the plots in the right column are narrower than in the left column.   Here is the code, and the plot is attached.  The "widths=c(2,1)" command in the plot_layout() didn't work.

layout <-
  "
AABB
CCDD
#EE#
"
ridge + laplace + horseshoe + FinnHorseshoe + spikeSlab + plot_layout(design = layout)

On Mon, Jan 3, 2022 at 1:41 PM Avi Gross <avi.e...@gmail.com> wrote:

David,

 

Thanks for your question as it made me think and search for packages and options that might do what you want. Oddly, centering is not something I see the packages caring about!  And, of course, sometimes you can get what you want by thinking outside the box. I note that if you are putting your graphs into a program that allows tables and centering, such as WORD or EXCEL, it becomes fairly easy to make an (invisible border?) table with the number of rows/columns you need and place images where you want and align some to be centered, horizontally and/or vertically within their cell. The sizes of the images as saved would remain fixed.

 

But if you want to remain within a package like patchwork, the documentation does suggest possibilities to get what you want albeit you might need to center it yourself. I am looking at this page, for example:

 

https://patchwork.data-imaginist.com/articles/guides/layout.html

 

There seem to be ways to ask it for a component to remain fixed and not be stretched. There is a method allowing inset_element() to place an image overlapping or within an image and I wonder if it could also be used to place it below the current row into an empty row and carefully offset to be in the middle.

 

The next clip indicates you can:

 

Further, inset_element() allows you to place the inset below the previous plot, should you choose to, and controlling clipping and tagging in the same way as wrap_elements().

p3 + inset_element(p1, left = 0.5, bottom = 0, right = 1, top = 0.5,

                   on_top = FALSE, align_to = 'full')

 

And note you can set heights and widths in some of the supplied functions to be the same for all as in:

                    plot_layout(widths = c(2, 1))

 

I have to admit that what you want is fairly basic and you wonder why it is not already touted as a built-in feature somewhere. People do like having things centered. What I have done in the past when the bottom row was not full is to play various games to fill it somewhat. This can include putting in an image of the author, putting in (large) text with some useful or useless phrases perhaps about the problem or methods used or even move something like the guides into that empty  slot.

 

Good Luck with finding a solution that works for you.

 

Avi


--
--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: https://github.com/hadley/devtools/wiki/Reproducibility
 
To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com
More options: http://groups.google.com/group/ggplot2

---
You received this message because you are subscribed to the Google Groups "ggplot2" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ggplot2+u...@googlegroups.com.
Rplot.pdf

Avi Gross

unread,
Jan 4, 2022, 9:08:14 AM1/4/22
to David Kaplan, ggplot2
dAVId,

Just to waste some time I tried their offset method but it takes fin tuning using numbers I am not understanding. The following sort of works for me when I added some padding on bottom and did the offset relative to the second row, first column trying to dangle another plot just below it and centered. It can let you all kinds of weird things and is neither easy or a good automated technique.

ridge +
  laplace +
  horseshoe +
  inset_element(spikeSlab, left = .4, bottom = -1.9, right = 1.6, top = 0) +
  FinnHorseshoe +
  plot_spacer() +
  plot_spacer() +
  plot_spacer() +
  plot_layout(ncol=2)

Getting it to be the approximate height and width is an art. This is not even close but looks centered.

image.png
Avi


On Mon, Jan 3, 2022 at 2:41 PM Avi Gross <avi.e...@gmail.com> wrote:

David,

 

Thanks for your question as it made me think and search for packages and options that might do what you want. Oddly, centering is not something I see the packages caring about!  And, of course, sometimes you can get what you want by thinking outside the box. I note that if you are putting your graphs into a program that allows tables and centering, such as WORD or EXCEL, it becomes fairly easy to make an (invisible border?) table with the number of rows/columns you need and place images where you want and align some to be centered, horizontally and/or vertically within their cell. The sizes of the images as saved would remain fixed.

 

But if you want to remain within a package like patchwork, the documentation does suggest possibilities to get what you want albeit you might need to center it yourself. I am looking at this page, for example:

 

https://patchwork.data-imaginist.com/articles/guides/layout.html

 

There seem to be ways to ask it for a component to remain fixed and not be stretched. There is a method allowing inset_element() to place an image overlapping or within an image and I wonder if it could also be used to place it below the current row into an empty row and carefully offset to be in the middle.

 

The next clip indicates you can:

 

Further, inset_element() allows you to place the inset below the previous plot, should you choose to, and controlling clipping and tagging in the same way as wrap_elements().

p3 + inset_element(p1, left = 0.5, bottom = 0, right = 1, top = 0.5,

                   on_top = FALSE, align_to = 'full')

 

And note you can set heights and widths in some of the supplied functions to be the same for all as in:

                    plot_layout(widths = c(2, 1))

 

I have to admit that what you want is fairly basic and you wonder why it is not already touted as a built-in feature somewhere. People do like having things centered. What I have done in the past when the bottom row was not full is to play various games to fill it somewhat. This can include putting in an image of the author, putting in (large) text with some useful or useless phrases perhaps about the problem or methods used or even move something like the guides into that empty  slot.

 

Good Luck with finding a solution that works for you.

 

Avi


On Mon, Jan 3, 2022 at 7:03 AM David Kaplan <cubsf...@gmail.com> wrote:

Avi Gross

unread,
Jan 4, 2022, 9:08:15 AM1/4/22
to David Kaplan, ggplot2

David,

 

Thanks for your question as it made me think and search for packages and options that might do what you want. Oddly, centering is not something I see the packages caring about!  And, of course, sometimes you can get what you want by thinking outside the box. I note that if you are putting your graphs into a program that allows tables and centering, such as WORD or EXCEL, it becomes fairly easy to make an (invisible border?) table with the number of rows/columns you need and place images where you want and align some to be centered, horizontally and/or vertically within their cell. The sizes of the images as saved would remain fixed.

 

But if you want to remain within a package like patchwork, the documentation does suggest possibilities to get what you want albeit you might need to center it yourself. I am looking at this page, for example:

 

https://patchwork.data-imaginist.com/articles/guides/layout.html

 

There seem to be ways to ask it for a component to remain fixed and not be stretched. There is a method allowing inset_element() to place an image overlapping or within an image and I wonder if it could also be used to place it below the current row into an empty row and carefully offset to be in the middle.

 

The next clip indicates you can:

 

Further, inset_element() allows you to place the inset below the previous plot, should you choose to, and controlling clipping and tagging in the same way as wrap_elements().

p3 + inset_element(p1, left = 0.5, bottom = 0, right = 1, top = 0.5,

                   on_top = FALSE, align_to = 'full')

 

And note you can set heights and widths in some of the supplied functions to be the same for all as in:

                    plot_layout(widths = c(2, 1))

 

I have to admit that what you want is fairly basic and you wonder why it is not already touted as a built-in feature somewhere. People do like having things centered. What I have done in the past when the bottom row was not full is to play various games to fill it somewhat. This can include putting in an image of the author, putting in (large) text with some useful or useless phrases perhaps about the problem or methods used or even move something like the guides into that empty  slot.

 

Good Luck with finding a solution that works for you.

 

Avi


On Mon, Jan 3, 2022 at 7:03 AM David Kaplan <cubsf...@gmail.com> wrote:

avi.e...@gmail.com

unread,
Jan 4, 2022, 9:08:16 AM1/4/22
to ggplot2
As I said, David, you can play with options and see what works. The widths and heights you set are global within a patch as in the same for all columns except you are sort of fighting the setup by having the last row be centered. I wonder if what might work is to select a LAYOUT like the following asking for 4 identical columns you set to the same widths as suggested earlier

AABB
CCDD
#EE#

If you now specify the width to be the same for all 4 to be 1 each it ought to work but as noted, has a flaw,:

layout <-
  "
AABB
CCDD
#EE#
"
ridge + laplace + horseshoe + FinnHorseshoe + spikeSlab + plot_layout(design = layout, widths = rep(1,4))

I believe the flaw is not in centering the bottom row but leaving out the last row does seem to make a nice symmetric result:

layout="
AB
CD"
ridge + laplace + horseshoe + FinnHorseshoe + plot_layout(design = layout, widths = rep(1,4))

I tried about a dozen variations including creating multiple parts patched together and this glitch persists. I suspect it is an inherent feature not easy to get around. May be time to ask the maintainer of the package why under such conditions, the top rows are no longer even and symmetrical.

Brad Udall

unread,
Jan 4, 2022, 10:16:07 AM1/4/22
to Avi Gross, David Kaplan, ggplot2

I’m not quite sure how I got on this list but a few quick observations.

 

A while back I found myself with lots of time invested in a ggplot graphic but no way to implement a tweak I needed to the final image.

 

I’ve always found ggplot a bit cryptic to use, despite Hadley’s goal of ease of use.

 

I ended up using the core routines that Hadley uses, ‘grobs’, I think, to solve my problem.

 

(There’s a book called R Graphics by Murrow that gets into these grob details.)

 

I don’t even really know what I did – it was trial and error all the way. Finally something worked.

 

After that experience, I decided to not use ggplot any more. Harsh, I know.

 

Since then I’ve mostly stayed with Base Graphics – I’ve never found anything I couldn’t do in Base, even if it usually takes more steps.

 

So, if you’re really desperate, you might get Murrow’s book and figure out how to work on the deeper level ggplot objects.                                                                                                                                                                                                                                                                   

 

I wish I had something better to say, but that’s my 2 cents.

 

Brad

 

 

 

 

 

 

 

From: ggp...@googlegroups.com <ggp...@googlegroups.com> on behalf of Avi Gross <avi.e...@gmail.com>
Date: Tuesday, January 4, 2022 at 7:08 AM
To: David Kaplan <cubsf...@gmail.com>
Cc: ggplot2 <ggp...@googlegroups.com>
Subject: Re: Centering a plot

dAVId,

 

Just to waste some time I tried their offset method but it takes fin tuning using numbers I am not understanding. The following sort of works for me when I added some padding on bottom and did the offset relative to the second row, first column trying to dangle another plot just below it and centered. It can let you all kinds of weird things and is neither easy or a good automated technique.

 

ridge +
  laplace +
  horseshoe +
  inset_element(spikeSlab, left = .4, bottom = -1.9, right = 1.6, top = 0) +
  FinnHorseshoe +
  plot_spacer() +
  plot_spacer() +
  plot_spacer() +
  plot_layout(ncol=2)

 

Getting it to be the approximate height and width is an art. This is not even close but looks centered.

 

Avi

 

 

On Mon, Jan 3, 2022 at 2:41 PM Avi Gross <avi.e...@gmail.com> wrote:

David,

 

Thanks for your question as it made me think and search for packages and options that might do what you want. Oddly, centering is not something I see the packages caring about!  And, of course, sometimes you can get what you want by thinking outside the box. I note that if you are putting your graphs into a program that allows tables and centering, such as WORD or EXCEL, it becomes fairly easy to make an (invisible border?) table with the number of rows/columns you need and place images where you want and align some to be centered, horizontally and/or vertically within their cell. The sizes of the images as saved would remain fixed.

 

But if you want to remain within a package like patchwork, the documentation does suggest possibilities to get what you want albeit you might need to center it yourself. I am looking at this page, for example:

 

https://patchwork.data-imaginist.com/articles/guides/layout.html

 

There seem to be ways to ask it for a component to remain fixed and not be stretched. There is a method allowing inset_element() to place an image overlapping or within an image and I wonder if it could also be used to place it below the current row into an empty row and carefully offset to be in the middle.

 

The next clip indicates you can:

 

Further, inset_element() allows you to place the inset below the previous plot, should you choose to, and controlling clipping and tagging in the same way as wrap_elements().

p3 + inset_element(p1, left = 0.5, bottom = 0, right = 1, top = 0.5,

                   on_top = FALSE, align_to = 'full')

 

And note you can set heights and widths in some of the supplied functions to be the same for all as in:

                    plot_layout(widths = c(2, 1))

 

I have to admit that what you want is fairly basic and you wonder why it is not already touted as a built-in feature somewhere. People do like having things centered. What I have done in the past when the bottom row was not full is to play various games to fill it somewhat. This can include putting in an image of the author, putting in (large) text with some useful or useless phrases perhaps about the problem or methods used or even move something like the guides into that empty  slot.

 

Good Luck with finding a solution that works for you.

 

Avi

 

On Mon, Jan 3, 2022 at 7:03 AM David Kaplan <cubsf...@gmail.com> wrote:

Actually, I found that this works, though I would like to make the bottom plot in the same width and height as the others.

 

(ridge | laplace) /
(horseshoe | FinnHorseshoe) /
(plot_spacer() | spikeSlab | plot_spacer())

 

 

On Sunday, January 2, 2022 at 9:08:06 AM UTC-6 David Kaplan wrote:

Greetings all,

 

Below you'll see a series of plots.  I would like the last plot to be centered below the plots in the second row but of the same height and width.  

 

David Kaplan

unread,
Jan 4, 2022, 10:21:52 AM1/4/22
to Avi Gross, ggplot2
Yea, this is really close.  I've been playing with the insert_element parameters but can't seem to fix the spike and slab plot.  It seems to cut off the top line.

Thanks

David

Brendan Kohrn

unread,
Jan 4, 2022, 10:33:59 AM1/4/22
to David Kaplan, Avi Gross, ggplot2
Don't know if this will be useful, but have you tried "arrangegrob" from the gridExtra package?  Add a blank plot as a spacer, and do something like this:

spacer_plot <- ggplot()
layout <- rbind(c(1,1,2,2),c(3,3,4,4),c(6,5,5,7))
final_plot <- arrangegrob(grobs = c(ridge, laplace, horseshoe, FinnHorseshoe, spikeSlab, spacer_plot, spacer_plot), layout_matrix = layout)




mark connolly

unread,
Jan 4, 2022, 11:04:47 AM1/4/22
to ggplot2
This seems to get a bit closer (though trial and error is not something you would like):
layout <- c(
  area(t=1, b=1, l=1, r=3),
  area(t=1, b=1, l=5, r=8),
  area(t=2, b=2, l=1, r=3),
  area(t=2, b=2, l=5, r=8),
  area(t=3, b=3, l=3, r=5)
)

ridge + laplace + horseshoe + FinnHorseshoe + spikeSlab + plot_layout(design = layout)

But I wonder if the issue is the fact you are plotting even and odd numbers of plots in the grid?    Maybe a question for patchwork?

eipi10

unread,
Jan 4, 2022, 12:37:02 PM1/4/22
to ggplot2
It looks like there are two issues we want to deal with. First, getting the bottom plot centered and with a panel that has the same shape and size as the other panels. Second, the first and second row of plots actually don’t quite line up vertically (the lower pair of panels have a different width than the upper pair). 

In the code below, we first lay out the top four plots as one unit and use plot_layout to put them in two rows. This lines up the top four plots. Then we add the third row using two calls to plot_spacer(), plus a call to plot_layout to get the widths. Finally, we put the top four plots and the single bottom plot together with a third call to plot_layout to get the heights.

It turns out that this doesn’t give us quite what we want. First, the bottom plot isn’t quite centered (which might have something to do with the margins around each component and around the whole layout). Second, the height of the bottom plot is a bit larger than 1/3 of the entire layout’s height (once again, maybe a margin issue, but I’m not sure). The only way I can think of to fix these issues is by tweaking the layout widths and heights, as I’ve done in the second code example below. 

Let me know if these are helpful.

Joel

(ridge + laplace +
    horseshoe + FinnHorseshoe + plot_layout(ncol=2)) /
  (plot_spacer() + spikeSlab + plot_spacer() + plot_layout(widths=c(0.5,1,0.5))) +
  plot_layout(heights=c(2,1))

Rplot.png

(ridge + laplace +
    horseshoe + FinnHorseshoe + plot_layout(ncol=2)) /
  (plot_spacer() + spikeSlab + plot_spacer() + plot_layout(widths=c(0.4,1,0.6))) +
  plot_layout(heights=c(2.1,0.9))

Rplot01.png
On Jan 4, 2022, at 8:04 AM, mark connolly <freddi...@gmail.com> wrote:

mark connolly

unread,
Jan 5, 2022, 9:21:37 AM1/5/22
to ggplot2
Very nice!  I swung and missed on specifying widths.  Your example helps me.  I have not seen patchwork before, but it is pretty sweet.
Reply all
Reply to author
Forward
0 new messages