Written and maintained by CASRAI Editorial Board
Last updated
In ggplot2, the line type is set with the linetype aesthetic. Give it a number from 0 to 6 or a name such as "dashed", or a short hexadecimal string such as "33" for a custom dash pattern. Set it outside aes() to give every line the same type, or inside aes() to let a variable choose the type for each group. This guide covers the seven named values, how the hex strings work, the linetype scales, and the errors people hit most often.
What line types do in research figures
Colour alone does not always survive a journal’s print workflow. A figure printed in greyscale, or read by someone who cannot tell two hues apart, loses the identity of its series. Mapping a second variable to linetype keeps the lines distinguishable without colour. Reference lines (a threshold, a baseline, a target) also benefit: geom_hline() and geom_vline() support the aesthetics alpha, colour, linetype and linewidth, so a dashed horizontal line can mark a cut-off without competing with the data lines.
For colour choices that work alongside line types, see ggplot color palettes. For line thickness in base R, see lwd in R.
Install or access
ggplot2 is an R package distributed through CRAN, R’s package repository, and is documented at ggplot2.tidyverse.org. Install it once and load it in each session:
install.packages("ggplot2")
library(ggplot2)
The tidyverse documentation is the reference for every argument shown below. For a wider introduction to building and saving plots, see ggplots in R.
Set a line type, step by step
The ggplot2 specification page defines a line type as “an integer or name”: 0 = blank, 1 = solid, 2 = dashed, 3 = dotted, 4 = dotdash, 5 = longdash, 6 = twodash.
| Integer | Name |
|---|---|
| 0 | blank |
| 1 | solid |
| 2 | dashed |
| 3 | dotted |
| 4 | dotdash |
| 5 | longdash |
| 6 | twodash |
Same type for every line
- Build a data frame with an x column, a y column and a grouping column.
d <- data.frame( x = rep(1:5, 2), y = c(2, 3, 5, 4, 6, 1, 2, 2, 3, 5), group = rep(c("control", "treated"), each = 5) ) - Pass
linetypeas a fixed value to the geom, outsideaes().ggplot(d, aes(x, y, group = group)) + geom_line(linetype = "dashed")
One type per group
- Map the grouping variable to
linetypeinsideaes(). ggplot2 assigns a type to each level and draws a legend.ggplot(d, aes(x, y, linetype = group)) + geom_line() - To remove the legend title, give the scale a
NULLname; the reference page forscale_linetype()documents thatname = NULLremoves the legend title.ggplot(d, aes(x, y, linetype = group)) + geom_line() + scale_linetype(name = NULL)
Custom dash patterns with hex strings
Beyond the seven named types, the specification page describes a string of 2, 4, 6 or 8 hexadecimal digits that “give the lengths of consecutive lengths”: on, then off, then on, and so on. Its examples: the string "33" means three units on followed by three off, and "3313" means three on, three off, one on, and finally three off.
ggplot(d, aes(x, y, group = group)) +
geom_line(linetype = "3313")
The same page notes that the five standard dash-dot line types correspond to the hex strings 44, 13, 1343, 73 and 2262, which is a useful starting point when you want a pattern slightly longer or shorter than a standard one.
Reference lines
ggplot(d, aes(x, y, linetype = group)) +
geom_line() +
geom_hline(yintercept = 3, linetype = "dotted")
The required argument is yintercept for geom_hline() and xintercept for geom_vline().
For a walk-through of drawing the line itself in base R and ggplot2, see plotting a line in R.
Output: reading the legend
When linetype is mapped inside aes(), the legend lists each level beside a sample of its line type. The legend title defaults to the variable name; set it with the name argument of the scale, or remove it with name = NULL. Line thickness is a separate aesthetic, linewidth. The specification page notes that, due to a historical error, the unit of linewidth is roughly 0.75 mm, and that changing it to exactly 1 mm would alter a very large number of existing plots.
Troubleshooting
Error when mapping a continuous variable to linetype
Continuous values cannot be mapped to line types unless scale_linetype_binned() is used. The reference page also states that because line types have no inherent order, mapping an ordered or continuous quantity to them is not advised. Convert the variable to a factor, or bin it, before mapping.
Linetype does not change along one line
An example comment in the geom_path() reference says that line type needs to be applied to a line as a whole, so it cannot be combined with a colour or size that varies across a single line. To change the type, split the data into separate groups.
Lines drawn with no visible pattern
The value 0 or the name "blank" draws nothing. If a series disappears, check that it was not assigned type 0.
The grouping is wrong
Lines are connected by the group aesthetic. Mapping linetype to a discrete variable creates groups automatically; with a fixed linetype, add group = ... as in the first example.
Free alternatives
Both approaches below are free and use the same seven named types.
| Tool | Argument | Named and integer types | Custom pattern strings |
|---|---|---|---|
| ggplot2 | linetype |
0 to 6, or blank, solid, dashed, dotted, dotdash, longdash, twodash | 2, 4, 6 or 8 hexadecimal digits |
| Base R graphics | lty |
0 to 6, or “blank”, “solid”, “dashed”, “dotted”, “dotdash”, “longdash”, “twodash” | An even number of non-zero hexadecimal characters, up to eight |
In base R, lty is a graphical parameter documented under par(). A comparison of both systems for line plots is in plotting a line in R.
FAQ
How many line types does ggplot2 have?
Seven named types, numbered 0 to 6 (blank, solid, dashed, dotted, dotdash, longdash, twodash), plus any custom pattern written as a hex string.
What does linetype = “33” mean?
Three units drawn, then three units skipped, repeated along the line.
Should I set linetype inside or outside aes()?
Outside aes() for one fixed type on the whole layer; inside aes() to let a variable choose the type and to get a legend.
Why can I not map a continuous variable to linetype?
The default linetype scale is for discrete values. Continuous values need scale_linetype_binned(), and line types have no inherent order.
Sources
- ggplot2 documentation, “Aesthetic specifications”: ggplot2.tidyverse.org/articles/ggplot2-specs.html (date checked: 2026-10-29)
- ggplot2 reference, scale_linetype reference page: ggplot2.tidyverse.org/reference/scale_linetype.html (date checked: 2026-10-29)
- ggplot2 reference, geom_hline and geom_vline reference page: ggplot2.tidyverse.org/reference/geom_abline.html (date checked: 2026-10-29)
- ggplot2 reference, geom_path and geom_line reference page: ggplot2.tidyverse.org/reference/geom_path.html (date checked: 2026-10-29)
- R documentation, par() graphical parameters: stat.ethz.ch/R-manual/R-devel/library/graphics/html/par.html (date checked: 2026-10-29)







