Smaller gap between two legends in one plot (e.g. color and size scale)
Asked Answered
P

2

31

how do I reduce the gap between two guides in one plot. In the example below, the two guides are from a color and size scale and I want to change the gap between the two so that the title 'size' is right below the legend-point for 1. Design-wise, it might not make sense in this example but in my actual application it does.

df=data.frame(x=rnorm(100),y=rnorm(100),color=factor(rbinom(100,1,0.5)),size=runif(100))
ggplot(df,aes(x=x,y=y,color=color,size=size)) + geom_point()

Edit: Here is the plot. I would like to make the gap highlighted by the green line and the arrow smaller.

enter image description here

Protease answered 31/12, 2012 at 16:34 Comment(5)
Are you talking about what are called 'scales' in both lattice and ggplot terminology, or are your referring to 'legends'?Pauper
I am talking about the legends on the left pf the plot called 'color' and 'size' in the example plot. I want to move to two closer together.Protease
you define the problem better, but possible duplicate? :/ #11367464Odoric
@AnthonyDamico no it is not a duplicate.Unmixed
@Anthony, I think your linked thread is about the spacing between the legend keys (the keys for 0' and 1' color legend in the example). My question is about the spacing between two legends as indicated with the green arrow.Protease
U
5

I tried to play to customize legend or guide parameters but I can't find a solution. I hope give a solution using ggplot2 settings.

Here 2 solutions based on the gtable and grid packages.

for the gtable solution, the code is inspired from this question.

enter image description here

  library(gtable)
  # Data transformation
  data <- ggplot_build(p)
  gtable <- ggplot_gtable(data)
  # Determining index of legends table
  lbox <- which(sapply(gtable$grobs, paste) == "gtable[guide-box]")
  # changing the space between the 2 legends: here -0.5 lines
  guide <- gtable$grobs[[lbox]]
  gtable$grobs[[lbox]]$heights <- unit.c(guide$heights[1:2],
                                    unit(-.5,'lines'),  ## you can the GAP here
                                    guide$heights[4:5])
  # Plotting
  grid.draw(gtable)

Similar using the grid package ( we redraw in the viewport of the legend)

pp <- grid.get('guide',grep=T)
 depth <- downViewport(pp$wrapvp$name)
 guide <- grid.get('guide',grep=T)
 grid.rect(gp=gpar(fill='white'))
 guide$heights <- unit.c(guide$heights[1:2],unit(-0.2,'lines'),guide$heights[4],unit(0.1,'lines'))
 grid.draw(guide)
 upViewport(depth)
Unmixed answered 1/1, 2013 at 10:26 Comment(11)
Thanks, I know that. My question is whether there is an option to move the two guides/two legends for the size and the color scale closer together.Protease
@user1318686 What if you append your answer with a picture to show your final output?Unmixed
Done. I would like to make the gap highlighted by the green line and the arrow smaller.Protease
I still don't see a small gap between two legends. Did you miss something?Blastoderm
Thanks! That seems to be a good approach to make the gap larger but I don't see how I can use it to make the gap smaller.Protease
@RomanLuštrik I show it just for demonstration. I don't know how much gap he wants. I will update my answer. I need to guess what the OP want each time!Unmixed
Yes, I get that idea and I see how it makes the gap bigger. row=3 makes it smaller compared to row=5 but it's still bigger compared to original plot, which corresponds to row=2. My goal is to make it smaller and row=1 obviously has a different effect.Protease
@user1318686 For some reasons I understand you want bigger gap not smaller one! In update my solution now, hope that help.Unmixed
Excellent! Thanks! One small suggestion for an edit: The gtable based solution also requires the guide object, which is only defined in the grid based solution. I think it would be good to add guide <- grid.get('guide',grep=T) to the first solution (it the line only works after plotting, right?) so that the code runs by itself.Protease
@user1318686! yes I forget to clean my workspace! I update my answer! without using the grid package.Unmixed
@Unmixed If we remove the two tittles of legend, how to set the gap between the two legends to 0? I mean merging the two legends into one. Thank you in advance!Luanneluanni
C
44

Now it seems to be possible using the theme parameters:

ggplot(df,aes(x=x,y=y,color=color,size=size)) + geom_point() + 
theme(legend.spacing.y = unit(-0.5, "cm"))

You can also try to decrease margins of the legends:

legend.margin = margin(-0.5,0,0,0, unit="cm")

or older

legend.margin=unit(0, "cm")
Cranwell answered 10/3, 2017 at 11:1 Comment(0)
U
5

I tried to play to customize legend or guide parameters but I can't find a solution. I hope give a solution using ggplot2 settings.

Here 2 solutions based on the gtable and grid packages.

for the gtable solution, the code is inspired from this question.

enter image description here

  library(gtable)
  # Data transformation
  data <- ggplot_build(p)
  gtable <- ggplot_gtable(data)
  # Determining index of legends table
  lbox <- which(sapply(gtable$grobs, paste) == "gtable[guide-box]")
  # changing the space between the 2 legends: here -0.5 lines
  guide <- gtable$grobs[[lbox]]
  gtable$grobs[[lbox]]$heights <- unit.c(guide$heights[1:2],
                                    unit(-.5,'lines'),  ## you can the GAP here
                                    guide$heights[4:5])
  # Plotting
  grid.draw(gtable)

Similar using the grid package ( we redraw in the viewport of the legend)

pp <- grid.get('guide',grep=T)
 depth <- downViewport(pp$wrapvp$name)
 guide <- grid.get('guide',grep=T)
 grid.rect(gp=gpar(fill='white'))
 guide$heights <- unit.c(guide$heights[1:2],unit(-0.2,'lines'),guide$heights[4],unit(0.1,'lines'))
 grid.draw(guide)
 upViewport(depth)
Unmixed answered 1/1, 2013 at 10:26 Comment(11)
Thanks, I know that. My question is whether there is an option to move the two guides/two legends for the size and the color scale closer together.Protease
@user1318686 What if you append your answer with a picture to show your final output?Unmixed
Done. I would like to make the gap highlighted by the green line and the arrow smaller.Protease
I still don't see a small gap between two legends. Did you miss something?Blastoderm
Thanks! That seems to be a good approach to make the gap larger but I don't see how I can use it to make the gap smaller.Protease
@RomanLuštrik I show it just for demonstration. I don't know how much gap he wants. I will update my answer. I need to guess what the OP want each time!Unmixed
Yes, I get that idea and I see how it makes the gap bigger. row=3 makes it smaller compared to row=5 but it's still bigger compared to original plot, which corresponds to row=2. My goal is to make it smaller and row=1 obviously has a different effect.Protease
@user1318686 For some reasons I understand you want bigger gap not smaller one! In update my solution now, hope that help.Unmixed
Excellent! Thanks! One small suggestion for an edit: The gtable based solution also requires the guide object, which is only defined in the grid based solution. I think it would be good to add guide <- grid.get('guide',grep=T) to the first solution (it the line only works after plotting, right?) so that the code runs by itself.Protease
@user1318686! yes I forget to clean my workspace! I update my answer! without using the grid package.Unmixed
@Unmixed If we remove the two tittles of legend, how to set the gap between the two legends to 0? I mean merging the two legends into one. Thank you in advance!Luanneluanni

© 2022 - 2024 — McMap. All rights reserved.