diff --git a/NEWS.md b/NEWS.md
index f96283e156..b06be03b5f 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,5 +1,7 @@
# ggplot2 (development version)
+* Extent the range of the line created by `geom_abline()` so that line ending
+ is not visible for large linewidths (@thomasp85, #4024)
* Make sure that default labels from default mappings doesn't overwrite default
labels from explicit mappings (@thomasp85, #2406)
diff --git a/R/geom-abline.r b/R/geom-abline.r
index 60161c1fc1..35b53ce57f 100644
--- a/R/geom-abline.r
+++ b/R/geom-abline.r
@@ -127,6 +127,12 @@ GeomAbline <- ggproto("GeomAbline", Geom,
draw_panel = function(data, panel_params, coord) {
ranges <- coord$backtransform_range(panel_params)
+ if (coord$clip == "on" && coord$is_linear()) {
+ # Ensure the line extends well outside the panel to avoid visible line
+ # ending for thick lines
+ ranges$x <- ranges$x + c(-1, 1) * diff(ranges$x)
+ }
+
data$x <- ranges$x[1]
data$xend <- ranges$x[2]
data$y <- ranges$x[1] * data$slope + data$intercept
diff --git a/tests/figs/geom-hline-vline-abline/cartesian-lines-intersect-mid-bars.svg b/tests/figs/geom-hline-vline-abline/cartesian-lines-intersect-mid-bars.svg
index 36e6c691c0..0343082192 100644
--- a/tests/figs/geom-hline-vline-abline/cartesian-lines-intersect-mid-bars.svg
+++ b/tests/figs/geom-hline-vline-abline/cartesian-lines-intersect-mid-bars.svg
@@ -31,7 +31,7 @@
-
+
diff --git a/tests/figs/geom-hline-vline-abline/flipped-lines-intersect-mid-bars.svg b/tests/figs/geom-hline-vline-abline/flipped-lines-intersect-mid-bars.svg
index c542172c56..3ce5f4107e 100644
--- a/tests/figs/geom-hline-vline-abline/flipped-lines-intersect-mid-bars.svg
+++ b/tests/figs/geom-hline-vline-abline/flipped-lines-intersect-mid-bars.svg
@@ -31,7 +31,7 @@
-
+