ggplot2 scale_color_manual() in R: Custom Colors for Groups
The scale_color_manual() function in ggplot2 assigns specific colors to specific factor levels in a plot. It is the right choice when you want EXACT colors (e.g., brand colors) instead of an automatic palette.
+ scale_color_manual(values = c("a" = "red", "b" = "blue"))
+ scale_color_manual(values = c("red","blue","green"))
+ scale_fill_manual(values = c(...)) # fill aesthetic
+ scale_color_brewer(palette = "Set1") # palette alternative
+ scale_color_viridis_d() # perceptual uniformNeed explanation? Read on for examples and pitfalls.
What scale_color_manual() does in one sentence
scale_color_manual(values = ...) maps each factor level of the color aesthetic to a specific color you provide. Used when default palette doesn't match brand or domain conventions.
Syntax
scale_color_manual(values, name = waiver(), labels = waiver(), ...). values is a named or positional vector of colors.
c("level" = "color") for safety; positional c("red","blue") is fragile if levels reorder.Five common patterns
1. Named values
2. Positional values
3. fill_manual variant
4. Use hex codes
5. Drop unused levels
c("level"="color") for STABLE mapping across plot revisions. Positional vectors break if you reorder factor levels.scale_color_manual() vs scale_color_brewer() vs scale_color_viridis
| Function | Source | Best for |
|---|---|---|
scale_color_manual() |
Custom | Exact colors |
scale_color_brewer() |
ColorBrewer palettes | Named palettes |
scale_color_viridis_d() |
Viridis | Perceptually uniform |
scale_color_grey() |
Greyscale | Print-safe |
A practical workflow
For team / brand consistency, define a colors vector once and reuse.
Common pitfalls
Pitfall 1: too few colors. If you have 5 levels but values has 3, ggplot recycles or errors. Provide one per level.
Pitfall 2: typos in named vector. A typo in "level" silently maps to default gray. Always check output.
scale_color_manual only sets COLOR aesthetic; for FILL, use scale_fill_manual(). They are separate scales.Try it yourself
Try it: Color mtcars points by cyl with custom colors red, green, blue. Save to ex_plot.
Click to reveal solution
Explanation: Named vector maps each cyl value to a specific color.
Related ggplot2 functions
After mastering scale_color_manual, look at:
scale_fill_manual(): same for fill aestheticscale_color_brewer(): ColorBrewer palettesscale_color_viridis_d(): viridis paletteaes(color = ...): map color aesthetictheme(): plot-wide styling
FAQ
What does scale_color_manual do in ggplot2?
scale_color_manual() assigns specific colors to factor levels for the color aesthetic. Used for custom / brand colors.
What is the difference between scale_color_manual and scale_fill_manual?
color is for line/point COLOR. fill is for area FILL (bars, polygons, ribbons). Use whichever aesthetic your geom uses.
How do I provide colors as hex codes?
Pass them in values: c("a" = "#1F77B4", "b" = "#FF7F0E").
What if I have more levels than colors?
ggplot recycles or errors. Always provide one color per level.
Should I use named or positional values?
Named for safety. Positional breaks silently if factor levels reorder.