• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Data Viz with Python and R

Learn to Make Plots in Python and R

  • Home
  • Seaborn
  • Matplotlib
  • ggplot2
  • Altair
  • About
    • Privacy Policy
  • Visualizing Activation Functions in Neural Networks
  • Confusion Matrix Calculator
  • Visualizing Dropout Rate in Neural Network
  • Visualizing Loss Functions in Neural Networks
  • Show Search
Hide Search

How To Fold Legend into Multiple Rows/Columns in ggplot2

datavizpyr · April 23, 2021 ·

Last updated on August 25, 2025

When plotting with ggplot2 in R, long legends can sometimes overflow, look cluttered, or even get cut off when placed at the top or bottom of a chart. This is especially common when you have many categories (e.g., years or groups) and want the legend to be clearly readable.

In this tutorial, we’ll learn how to wrap a long ggplot2 legend into multiple rows or columns using the guides() and guide_legend() functions. With step-by-step examples, you’ll see how to handle legends created by both color and fill aesthetics.

Table of Contents
  • Setup
  • Example: Long Legend at Bottom
  • Wrap Legend (color) into Two Rows
  • Wrap Legend (fill) into Two Rows
  • Make a Multi-Column Vertical Legend (ncol)
  • Tips for Cleaner Wrapped Legends
  • Conclusion
  • FAQs

Setup

We’ll use tidyverse and the gapminder dataset to produce examples with enough categories to trigger a long legend. A neutral theme helps you focus on the layout of the legend rather than the chart styling.

library(tidyverse)
library(gapminder)
# set theme_bw()
theme_set(theme_bw(16))

Example plot with long legend

Let’s start with a scatter plot colored by continent. Moving the legend to the bottom often makes it span horizontally; with many categories, it can look cramped or overflow the plotting area. This “problem state” helps us see the benefit of wrapping.

gapminder |>
  ggplot(aes(gdpPercap,lifeExp, color=continent)) +
  geom_point() +
  scale_x_log10()+
  theme(legend.position="bottom")

Note that the legend on the bottom of the plot is too long and gets cut out of the plot.

ggplot with long legend
ggplot with long legend at bottom

Wrap Legend (color) into Two Rows

To fold a long horizontal legend into multiple rows, use guides() with guide_legend() and set nrow. Since the legend is created by color, we target the color guide. Adding byrow = TRUE lays items out row-wise, which is usually more natural for a bottom legend.

gapminder |>
  ggplot(aes(gdpPercap,lifeExp, color=continent)) +
  geom_point() +
  scale_x_log10()+
  theme(legend.position = "bottom")+
  guides(color=guide_legend(nrow=2, byrow=TRUE))

And we get scatterplot with two rows for legend’s values at the bottom of the plot.

ggplot2 legend in two rows
ggplot2 legend in two rows

Wrap Legend (fill) into Two Rows

If your legend is generated by the fill aesthetic (for example, grouped boxplots), you must target fill in guides(). Below, we simplify the data and convert year to a factor to produce multiple legend entries, then wrap them into two rows at the top of the plot.

To show that let us make a grouped boxplot. First, let us simplify gapminder data to make grouped boxplot.

df <- gapminder |>
  filter(continent != "Oceania")%>% 
  filter(year %in% c(1952,1962,1972,1982,1992,2002)) %>%
  mutate(year=factor(year))

We make grouped boxplot and add legend with “fill” argument. And use guides() function with fill argument specifying the number of rows for legend.

df |>
  ggplot(aes(continent,lifeExp, fill=year)) +
  geom_boxplot() +
  theme(legend.position = "top")+
  guides(fill=guide_legend(nrow=2, byrow=TRUE))

In this example, we have two rows of legend on top of the plot.

ggplot2 legend in two rows
ggplot2 legend in two rows with guides fill

Make a Multi-Column Vertical Legend (ncol)

When the legend is on the right (vertical stack), a long legend can also be tightened by splitting it into multiple columns. In that case, use ncol instead of nrow. This is helpful when you want to reduce the chart’s height impact from a tall legend.

gapminder |>
  ggplot(aes(gdpPercap, lifeExp, color = continent)) +
  geom_point() +
  scale_x_log10() +
  theme(legend.position = "right") +
  guides(color = guide_legend(ncol = 2)) +
  labs(
    title = "Vertical Legend with Two Columns",
    subtitle = "guides(color = guide_legend(ncol = 2))",
    x = "GDP per capita (log10)",
    y = "Life expectancy"
  )
ggplot2: Vertical Legend with Two Columns
ggplot2: Vertical Legend with Two Columns

Tips for Cleaner Wrapped Legends

  • Shorten labels: Consider abbreviations or concise labels if categories are verbose.
  • Adjust spacing: theme(legend.text = element_text(size = 12)) can improve legibility without causing overflow.
  • Order intentionally: Reorder factor levels to group related items on the same row/column.
  • Match orientation to placement: Use nrow for horizontal (top/bottom) and ncol for vertical (left/right) legends.

Conclusion

Wrapping a long legend into multiple rows or columns in ggplot2 is easy with guide_legend(). By specifying nrow or ncol, you can split the legend items across lines and prevent them from being cut off when placed at the top or bottom of the plot. This small adjustment improves readability, especially in publications, dashboards, or presentations where space is limited.

Frequently Asked Questions (FAQs)

  • What if my wrapped legend still crowds the plot?
    Consider tightening plot margins, moving the legend outside the plotting panel (via theme tweaks), or shortening category labels so they fit more comfortably across rows/columns.
  • Should I wrap a legend or remove it entirely?
    If the legend is essential for decoding the chart, keep it and wrap it. If your plot is labeled directly (e.g., annotations or facet labels make categories obvious), removing the legend may reduce clutter.
  • How can I improve readability for print or slides?
    Increase legend text size, ensure good color contrast, and reduce the number of categories shown. Larger keys and succinct labels help when viewed from a distance.
  • What if my categories have very long names?
    Use shorter labels or line breaks in labels. You can also rotate or wrap legend text via theme settings, but simpler labels usually yield the cleanest results.
  • Will wrapping change the order of legend items?
    Wrapping preserves the order; it only changes the layout. If you need a different order, reorder the factor levels in your data first so the legend reflects your intended grouping.


Explore the Complete ggplot2 Guide

35+ tutorials with code: scatterplots, boxplots, themes, annotations, facets, and more—tested and beginner-friendly.

Visit the ggplot2 Hub → No fluff—just code and visuals.

Related posts:

Customizing Mean mark to boxplot with ggplot2How To Show Mean Value in Boxplots with ggplot2? Scatterplot with marginal multi-histogram with ggExtraHow To Make Scatterplot with Marginal Histograms in R? Default Thumbnail4 Ways to have Plots Side by side in ggplot2 Default ThumbnailHow to make rolling mean line plot of stock data

Filed Under: ggplot2, R Tagged With: ggplot2 legend two rows

Primary Sidebar

Python & R Viz Hubs

  • Seaborn Guide & Cookbook
  • ggplot2 Guide & Cookbook
  • Matplotlib Guide & Cookbook
  • Confusion Matrix Calculator
  • Visualizing Activation Functions
  • Visualizing Dropout
  • Visualizing Loss Functions

Buy Me a Coffee

Copyright © 2026 · Daily Dish Pro on Genesis Framework · WordPress · Log in

Go to mobile version