Search code examples
rggplot2plotlegend

How to center legend text in ggplot


I have a plot that looks like this: enter image description here

I used these data and code to produce it:

structure(list(zone = c("Zone 1", "Zone 2", "Zone 3", "Zone 4", 
"Zone 5", "Total", "Zone 1", "Zone 2", "Zone 3", "Zone 4", "Zone 5", 
"Total"), effort = c(3226, 4705, 2443, 131, 276, 10781, 1757, 
7293, 1631, 34.4, 442, 11157), creelyear = c("2013-2014", "2013-2014", 
"2013-2014", "2013-2014", "2013-2014", "2013-2014", "2022-2023", 
"2022-2023", "2022-2023", "2022-2023", "2022-2023", "2022-2023"
)), class = "data.frame", row.names = c(NA, -12L))
df %>% 
  ggplot(aes(x= zone, y= effort, fill=creelyear)) +
  geom_bar(position="dodge",  stat="identity", color = "black")  +                                                      #Select data for plotting
  scale_y_continuous(labels = comma, name = "Pressure (h/km)",
                     limits = c(0,12000), expand = c(0, 0))  +       #Change y axis name and expand so bars touch y axis
  scale_fill_manual(name = "", labels = c("2013-2014", "2022-2023"), values = c("#000000","#d11141"))+
  scale_x_discrete(limit = c("Zone 1", "Zone 2", "Zone 3", "Zone 4", "Zone 5", "Total")) +
  xlab("Zone") +                                                                  #Change name of x axis
  theme(legend.position = 'top',                                                    #Select legend position
        legend.spacing.x = unit(1.0, 'cm'),                                         #Select legend spacing value and units
        legend.background = element_blank(),
        legend.box.background = element_rect(colour = "black"),
        legend.text = element_text(margin = margin(r = 6.2, unit = "cm"), hjust = 2),
        panel.background = element_rect(fill='transparent'),                        #Set panel background to transparent for presentations
        plot.background = element_rect(fill='transparent', color = "transparent"),  #Set plot background to transparent for presentations
        panel.grid.major = element_blank(),                                         #Remove major gridlines
        panel.grid.minor = element_blank(),
        panel.border = element_rect(colour = "black", fill=NA, size=1))

How can I center the text in legend and give some more space between the colors and text so it looks more aesthetically pleasing?


Solution

  • Here are some potentially helpful options for you. legend.key.spacing.x and legend.margin is what I would use to try to achieve what you want with the top spanning legend. Just keep in mind you are specifying an exact measurement of spacing and that will depend on your total image dimensions and plot size, etc. First & Second show key spacing. Third shows the combination of key spacing and margin (the 4 margin numbers are upper, right, lower and left padding). Fourth is what I would personally do if I were you.

    library(ggplot2)
    df <- structure(list(zone = c("Zone 1", "Zone 2", "Zone 3", "Zone 4", 
        "Zone 5", "Total", "Zone 1", "Zone 2", "Zone 3", "Zone 4", "Zone 5", 
        "Total"), effort = c(3226, 4705, 2443, 131, 276, 10781, 1757, 
            7293, 1631, 34.4, 442, 11157), creelyear = c("2013-2014", "2013-2014", 
                "2013-2014", "2013-2014", "2013-2014", "2013-2014", "2022-2023", 
                "2022-2023", "2022-2023", "2022-2023", "2022-2023", "2022-2023"
            )), class = "data.frame", row.names = c(NA, -12L))
    
    base <- df |> 
        ggplot(aes(x= zone, y= effort, fill=creelyear)) +
        geom_bar(position="dodge",  stat="identity", color = "black") +
        scale_y_continuous(labels = scales::comma, name = "Pressure (h/km)",
            limits = c(0,12000), expand = c(0, 0)) +
        scale_fill_manual(labels = c("2013-2014", "2022-2023"), values = c("#000000","#d11141")) + # No need to specify name = "" if you set legend title to element_blank()
        scale_x_discrete(limit = c("Zone 1", "Zone 2", "Zone 3", "Zone 4", "Zone 5", "Total")) +
        xlab("Zone") +
        theme(panel.background = element_rect(fill='transparent'),
            plot.background = element_rect(fill='transparent', color = "transparent"),
            panel.grid.major = element_blank(),
            panel.grid.minor = element_blank(),
            panel.border = element_rect(colour = "black", fill=NA, linewidth=1))
    base +
        theme(legend.position = 'top',
            legend.key.spacing.x = unit(1.5, 'cm'),
            legend.background = element_rect(colour = "black"),
            legend.title = element_blank())
    

    base +
        theme(legend.position = 'top',
            legend.key.spacing.x = unit(10, 'cm'),
            legend.background = element_rect(colour = "black"),
            legend.title = element_blank())
    

    base +
        theme(legend.position = 'top',
            legend.key.spacing.x = unit(7.5, 'cm'),
            legend.margin = margin(5,50,5,50),
            legend.background = element_rect(colour = "black"),
            legend.title = element_blank())
    

    base +
        theme(legend.position = 'inside',
            legend.byrow = TRUE,
            legend.justification.inside = c(0.025, 0.975),
            legend.background = element_rect(colour = "black"),
            legend.title = element_blank())
    

    Created on 2024-05-06 with reprex v2.1.0