Home > OS >  Vertical Position of One of Two Legends in ggplot2 graphic
Vertical Position of One of Two Legends in ggplot2 graphic

Time:11-19

Is it possible to control the position of one relative to the other in a ggplot created graphic with two legends?

In the simple graphic below, I'm trying to vertically align the legend key for "Normal" with the "Some color" legend key. I'd like the red line to be the same height on the graphic as the center of color bar.

The first image below is where I'm stuck. The 2nd image below is the desired result, if a single legend can be moved.

A reproducable example is provided below. In this case, the title of the "Normal" legend is blank and I'm using the label only. I tried using label.vjust=0.5 (or 1) option in the legend_guide but it's a small vertical move and the red line does not move with it.

my attempt

my desired result

An example:

library(ggplot2) 
library(dplyr)

tt <- tibble(a=runif(15))
tt <- tt %>% mutate(n=row_number())

tt %>% ggplot()   
  geom_col( aes(x=n,y=a,fill=a))   
  geom_line(aes(x=n,y=a,color='Normal'),size=1)  
  theme_bw()   
  scale_color_manual(values=c('Normal'='red'))   
  labs(title='A Title',
       x='Some Numbers',
       y='The Y-Axis',
       color = '',
       fill='Some Color')   
  theme(plot.title   = element_text(hjust=0.5),
        axis.title.x = element_blank(),
        legend.title = element_text(size=13,face='bold'),
        legend.text  = element_text(size=13,face='bold'),
        legend.direction = "horizontal", 
        legend.position = "bottom",
        legend.key.width=unit(1.0,"cm"),
        legend.key.height=unit(.25,"cm"),
        legend.box.background = element_blank(),
        legend.justification = "center",
        legend.margin = margin(0.,0.,0.,0., unit="cm"),
        legend.background = element_blank(),
        plot.margin = margin(0.5, 0, 0, 0, "cm"))  
  guides(fill = guide_colorbar(title.position = "top",
                               title.hjust = 0.5),
         color = guide_legend(title.position = "top", 
                              label.vjust = 0.5, #centres the title horizontally
                              label.position = "top",
                              order=1)
                              )

Thanks for any suggestions.

CodePudding user response:

Bit of a hack, but if you wanna fine tune plots like this, I guess there's hardly any other way (or you make a fake legend).

Assign value " " (space!) to your aesthetic and map the color to this. Thus, the legend won't have a visible label and you can place it "bottom".

P.S you should always set.seed before running sampling functions.

library(tidyverse)
tt <- tibble(a=runif(15))
tt <- tt %>% mutate(n=row_number())

data.frame()
#> data frame with 0 columns and 0 rows
tt %>% ggplot()   
  geom_col( aes(x=n,y=a,fill=a))   
  geom_line(aes(x=n,y=a, color = " "), size=1)  
  theme_bw()   
  labs(title='A Title',
       x='Some Numbers',
       y='The Y-Axis',
       fill='Some Color', 
       color = "Normal")  
  theme(legend.direction = "horizontal", 
        legend.position = "bottom")  
  scale_color_manual(values=c(' '='red')) 
  guides(fill = guide_colorbar(title.position = "top",
                               title.hjust = 0.5),
         color = guide_legend(title.position = "top", 
                              label.vjust = 0.5, #centres the title horizontally
                              label.position = "bottom",
                              order=1)
  )

Created on 2021-11-17 by the reprex package (v2.0.1)

  • Related