diff --git a/NAMESPACE b/NAMESPACE
index be51aed9..125ef943 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -41,6 +41,7 @@ importFrom(graphics,plot.new)
 importFrom(graphics,plot.window)
 importFrom(graphics,points)
 importFrom(graphics,polygon)
+importFrom(graphics,polypath)
 importFrom(graphics,rasterImage)
 importFrom(graphics,rect)
 importFrom(graphics,segments)
diff --git a/NEWS.md b/NEWS.md
index 3c854978..b132c706 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -13,6 +13,7 @@ New features:
   - `type = "boxplot"`. Simultaneously enables `plt(numeric ~ factor)`
   support, first raised in #2, so that a boxplot is automatically plotted if a
   numeric is plotted against a factor. (#154 @grantmcdermott)
+  - `type = "polypath`. (#159 @grantmcdermott)
 
 Misc:
 
diff --git a/R/draw_legend.R b/R/draw_legend.R
index 44558138..3ef30768 100644
--- a/R/draw_legend.R
+++ b/R/draw_legend.R
@@ -151,7 +151,7 @@ draw_legend = function(
   if (!exists("title", where = legend_args)) legend_args[["title"]] = by_dep
   if (is.null(legend_args[["pch"]])) legend_args[["pch"]] = pch
   if (is.null(legend_args[["lty"]])) legend_args[["lty"]] = lty
-  if (!is.null(type) && !(type %in% c("p", "ribbon", "polygon"))) {
+  if (!is.null(type) && !(type %in% c("p", "ribbon", "polygon", "polypath"))) {
     if (is.null(legend_args[["lwd"]])) legend_args[["lwd"]] = lwd
   }
   if (is.null(legend_args[["col"]])) legend_args[["col"]] = col
@@ -166,10 +166,10 @@ draw_legend = function(
   ) {
     legend_args[["pt.cex"]] = cex
   }
-  if (type %in% c("ribbon", "polygon", "boxplot") || isTRUE(gradient)) {
+  if (type %in% c("ribbon", "polygon", "polypath", "boxplot") || isTRUE(gradient)) {
     legend_args[["pch"]] = 22
     if (is.null(legend_args[["pt.cex"]])) legend_args[["pt.cex"]] = 3.5
-    if (is.null(legend_args[["pt.lwd"]]) && (!is.null(type) && !(type %in% c("polygon", "boxplot")))) {
+    if (is.null(legend_args[["pt.lwd"]]) && (!is.null(type) && !(type %in% c("polygon", "polypath", "boxplot")))) {
       legend_args[["pt.lwd"]] = 0
     }
     if (is.null(legend_args[["y.intersp"]])) legend_args[["y.intersp"]] = 1.25
diff --git a/R/tinyplot.R b/R/tinyplot.R
index 1293627e..fbf3e7d5 100644
--- a/R/tinyplot.R
+++ b/R/tinyplot.R
@@ -74,10 +74,10 @@
 #'   and "h" for histogram-like vertical lines. Specifying "n" produces an empty
 #'   plot over the extent of the data, but with no internal elements.
 #'   - Additional tinyplot types: "boxplot" for boxplots, "density" for
-#'   densities,  "pointrange" or "errorbar" for segment intervals, and
-#'   "polygon", "ribbon" or "area" for polygon intervals (where area plots are a
-#'   special case of ribbon plots with `ymin` set to 0 and `ymax` set to `y`;
-#'   see below).
+#'   densities, "polygon" or "polypath" for polygons,  "pointrange" or"errorbar"
+#'   for segment intervals, and "ribbon" or "area" for polygon intervals (where
+#'   area plots are a special case of ribbon plots with `ymin` set to 0 and
+#'   `ymax` set to `y`; see below).
 #' @param xlim the x limits (x1, x2) of the plot. Note that x1 > x2 is allowed
 #'   and leads to a ‘reversed axis’. The default value, NULL, indicates that
 #'   the range of the `finite` values to be plotted should be used.
@@ -262,7 +262,7 @@
 #' without causing unexpected changes to the output.
 #'   
 #' @importFrom grDevices adjustcolor colorRampPalette extendrange palette palette.colors palette.pals hcl.colors hcl.pals xy.coords png jpeg pdf svg dev.off dev.new dev.list
-#' @importFrom graphics abline arrows axis Axis box grconvertX grconvertY lines par plot.default plot.new plot.window points polygon segments title mtext text rect
+#' @importFrom graphics abline arrows axis Axis box grconvertX grconvertY lines par plot.default plot.new plot.window points polygon polypath segments title mtext text rect
 #' @importFrom utils modifyList head tail
 #' @importFrom stats na.omit
 #' @importFrom tools file_ext
@@ -705,7 +705,7 @@ tinyplot.default = function(
   by_ordered = FALSE
   by_continuous = !is.null(by) && inherits(by, c("numeric", "integer"))
   # manual overrides with warning
-  if (isTRUE(by_continuous) && type %in% c("l", "b", "o", "ribbon", "polygon", "boxplot")) {
+  if (isTRUE(by_continuous) && type %in% c("l", "b", "o", "ribbon", "polygon", "polypath", "boxplot")) {
     warning("\nContinuous legends not supported for this plot type. Reverting to discrete legend.")
     by_continuous = FALSE
   } else if (!is.null(by)){
@@ -1419,6 +1419,17 @@ tinyplot.default = function(
           lty = ilty,
           lwd = ilwd
         )
+      } else if (type == "polypath") {
+        irule = ifelse(!is.null(dots[["rule"]]), dots[["rule"]], "winding")
+        polypath(
+          x = xx,
+          y = yy,
+          border = icol,
+          col = ibg,
+          lty = ilty,
+          lwd = ilwd,
+          rule = irule
+        )
       } else if (type == "boxplot") {
         horizontal = ifelse(!is.null(dots[["horizontal"]]), dots[["horizontal"]], FALSE)
         boxwex_xx = ifelse(!is.null(dots[["boxwex"]]), dots[["boxwex"]], 0.8)
diff --git a/inst/tinytest/_tinysnapshot/polypath_disjoint_evenodd.svg b/inst/tinytest/_tinysnapshot/polypath_disjoint_evenodd.svg
new file mode 100644
index 00000000..23a9cce1
--- /dev/null
+++ b/inst/tinytest/_tinysnapshot/polypath_disjoint_evenodd.svg
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' class='svglite' width='504.00pt' height='504.00pt' viewBox='0 0 504.00 504.00'>
+<defs>
+  <style type='text/css'><![CDATA[
+    .svglite line, .svglite polyline, .svglite polygon, .svglite path, .svglite rect, .svglite circle {
+      fill: none;
+      stroke: #000000;
+      stroke-linecap: round;
+      stroke-linejoin: round;
+      stroke-miterlimit: 10.00;
+    }
+    .svglite text {
+      white-space: pre;
+    }
+  ]]></style>
+</defs>
+<rect width='100%' height='100%' style='stroke: none; fill: #FFFFFF;'/>
+<defs>
+  <clipPath id='cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA='>
+    <rect x='0.00' y='0.00' width='504.00' height='504.00' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='34.47' text-anchor='middle' style='font-size: 14.40px; font-weight: bold; font-family: "Liberation Sans";' textLength='128.77px' lengthAdjust='spacingAndGlyphs'>Disjoint rectangles</text>
+</g>
+<defs>
+  <clipPath id='cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng=='>
+    <rect x='59.04' y='59.04' width='414.72' height='371.52' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng==)'>
+<path d='M 74.40 416.80 L 74.40 287.80 L 218.40 287.80 L 218.40 416.80 ZM 314.40 201.80 L 458.40 201.80 L 458.40 72.80 L 314.40 72.80 Z' style='fill-rule: evenodd; fill: #BEBEBE; stroke-width: 0.75;' />
+</g>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='56.16' text-anchor='middle' style='font-size: 12.00px; font-family: "Liberation Sans";' textLength='74.07px' lengthAdjust='spacingAndGlyphs'>Rule:evenodd</text>
+</g>
+</svg>
diff --git a/inst/tinytest/_tinysnapshot/polypath_disjoint_winding.svg b/inst/tinytest/_tinysnapshot/polypath_disjoint_winding.svg
new file mode 100644
index 00000000..fd8bf68f
--- /dev/null
+++ b/inst/tinytest/_tinysnapshot/polypath_disjoint_winding.svg
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' class='svglite' width='504.00pt' height='504.00pt' viewBox='0 0 504.00 504.00'>
+<defs>
+  <style type='text/css'><![CDATA[
+    .svglite line, .svglite polyline, .svglite polygon, .svglite path, .svglite rect, .svglite circle {
+      fill: none;
+      stroke: #000000;
+      stroke-linecap: round;
+      stroke-linejoin: round;
+      stroke-miterlimit: 10.00;
+    }
+    .svglite text {
+      white-space: pre;
+    }
+  ]]></style>
+</defs>
+<rect width='100%' height='100%' style='stroke: none; fill: #FFFFFF;'/>
+<defs>
+  <clipPath id='cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA='>
+    <rect x='0.00' y='0.00' width='504.00' height='504.00' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='34.47' text-anchor='middle' style='font-size: 14.40px; font-weight: bold; font-family: "Liberation Sans";' textLength='128.77px' lengthAdjust='spacingAndGlyphs'>Disjoint rectangles</text>
+</g>
+<defs>
+  <clipPath id='cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng=='>
+    <rect x='59.04' y='59.04' width='414.72' height='371.52' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng==)'>
+<path d='M 74.40 416.80 L 74.40 287.80 L 218.40 287.80 L 218.40 416.80 ZM 314.40 201.80 L 458.40 201.80 L 458.40 72.80 L 314.40 72.80 Z' style='fill-rule: nonzero; fill: #BEBEBE; stroke-width: 0.75;' />
+</g>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='56.16' text-anchor='middle' style='font-size: 12.00px; font-family: "Liberation Sans";' textLength='68.71px' lengthAdjust='spacingAndGlyphs'>Rule:winding</text>
+</g>
+</svg>
diff --git a/inst/tinytest/_tinysnapshot/polypath_nested_ca_evenodd.svg b/inst/tinytest/_tinysnapshot/polypath_nested_ca_evenodd.svg
new file mode 100644
index 00000000..7d837ff7
--- /dev/null
+++ b/inst/tinytest/_tinysnapshot/polypath_nested_ca_evenodd.svg
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' class='svglite' width='504.00pt' height='504.00pt' viewBox='0 0 504.00 504.00'>
+<defs>
+  <style type='text/css'><![CDATA[
+    .svglite line, .svglite polyline, .svglite polygon, .svglite path, .svglite rect, .svglite circle {
+      fill: none;
+      stroke: #000000;
+      stroke-linecap: round;
+      stroke-linejoin: round;
+      stroke-miterlimit: 10.00;
+    }
+    .svglite text {
+      white-space: pre;
+    }
+  ]]></style>
+</defs>
+<rect width='100%' height='100%' style='stroke: none; fill: #FFFFFF;'/>
+<defs>
+  <clipPath id='cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA='>
+    <rect x='0.00' y='0.00' width='504.00' height='504.00' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='34.47' text-anchor='middle' style='font-size: 14.40px; font-weight: bold; font-family: "Liberation Sans";' textLength='385.56px' lengthAdjust='spacingAndGlyphs'>Nested rectangles, outer clockwise, inner anti-clockwise</text>
+</g>
+<defs>
+  <clipPath id='cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng=='>
+    <rect x='59.04' y='59.04' width='414.72' height='371.52' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng==)'>
+<path d='M 74.40 416.80 L 74.40 72.80 L 458.40 72.80 L 458.40 416.80 ZM 122.40 373.80 L 410.40 373.80 L 410.40 115.80 L 122.40 115.80 Z' style='fill-rule: evenodd; fill: #BEBEBE; stroke-width: 0.75;' />
+</g>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='56.16' text-anchor='middle' style='font-size: 12.00px; font-family: "Liberation Sans";' textLength='74.07px' lengthAdjust='spacingAndGlyphs'>Rule:evenodd</text>
+</g>
+</svg>
diff --git a/inst/tinytest/_tinysnapshot/polypath_nested_ca_winding.svg b/inst/tinytest/_tinysnapshot/polypath_nested_ca_winding.svg
new file mode 100644
index 00000000..915cfec2
--- /dev/null
+++ b/inst/tinytest/_tinysnapshot/polypath_nested_ca_winding.svg
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' class='svglite' width='504.00pt' height='504.00pt' viewBox='0 0 504.00 504.00'>
+<defs>
+  <style type='text/css'><![CDATA[
+    .svglite line, .svglite polyline, .svglite polygon, .svglite path, .svglite rect, .svglite circle {
+      fill: none;
+      stroke: #000000;
+      stroke-linecap: round;
+      stroke-linejoin: round;
+      stroke-miterlimit: 10.00;
+    }
+    .svglite text {
+      white-space: pre;
+    }
+  ]]></style>
+</defs>
+<rect width='100%' height='100%' style='stroke: none; fill: #FFFFFF;'/>
+<defs>
+  <clipPath id='cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA='>
+    <rect x='0.00' y='0.00' width='504.00' height='504.00' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='34.47' text-anchor='middle' style='font-size: 14.40px; font-weight: bold; font-family: "Liberation Sans";' textLength='385.56px' lengthAdjust='spacingAndGlyphs'>Nested rectangles, outer clockwise, inner anti-clockwise</text>
+</g>
+<defs>
+  <clipPath id='cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng=='>
+    <rect x='59.04' y='59.04' width='414.72' height='371.52' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng==)'>
+<path d='M 74.40 416.80 L 74.40 72.80 L 458.40 72.80 L 458.40 416.80 ZM 122.40 373.80 L 410.40 373.80 L 410.40 115.80 L 122.40 115.80 Z' style='fill-rule: nonzero; fill: #BEBEBE; stroke-width: 0.75;' />
+</g>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='56.16' text-anchor='middle' style='font-size: 12.00px; font-family: "Liberation Sans";' textLength='68.71px' lengthAdjust='spacingAndGlyphs'>Rule:winding</text>
+</g>
+</svg>
diff --git a/inst/tinytest/_tinysnapshot/polypath_nested_cc_evenodd.svg b/inst/tinytest/_tinysnapshot/polypath_nested_cc_evenodd.svg
new file mode 100644
index 00000000..68a4715c
--- /dev/null
+++ b/inst/tinytest/_tinysnapshot/polypath_nested_cc_evenodd.svg
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' class='svglite' width='504.00pt' height='504.00pt' viewBox='0 0 504.00 504.00'>
+<defs>
+  <style type='text/css'><![CDATA[
+    .svglite line, .svglite polyline, .svglite polygon, .svglite path, .svglite rect, .svglite circle {
+      fill: none;
+      stroke: #000000;
+      stroke-linecap: round;
+      stroke-linejoin: round;
+      stroke-miterlimit: 10.00;
+    }
+    .svglite text {
+      white-space: pre;
+    }
+  ]]></style>
+</defs>
+<rect width='100%' height='100%' style='stroke: none; fill: #FFFFFF;'/>
+<defs>
+  <clipPath id='cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA='>
+    <rect x='0.00' y='0.00' width='504.00' height='504.00' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='34.47' text-anchor='middle' style='font-size: 14.40px; font-weight: bold; font-family: "Liberation Sans";' textLength='235.17px' lengthAdjust='spacingAndGlyphs'>Nested rectangles, both clockwise</text>
+</g>
+<defs>
+  <clipPath id='cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng=='>
+    <rect x='59.04' y='59.04' width='414.72' height='371.52' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng==)'>
+<path d='M 74.40 416.80 L 74.40 72.80 L 458.40 72.80 L 458.40 416.80 ZM 122.40 373.80 L 122.40 115.80 L 410.40 115.80 L 410.40 373.80 Z' style='fill-rule: evenodd; fill: #BEBEBE; stroke-width: 0.75;' />
+</g>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='56.16' text-anchor='middle' style='font-size: 12.00px; font-family: "Liberation Sans";' textLength='74.07px' lengthAdjust='spacingAndGlyphs'>Rule:evenodd</text>
+</g>
+</svg>
diff --git a/inst/tinytest/_tinysnapshot/polypath_nested_cc_winding.svg b/inst/tinytest/_tinysnapshot/polypath_nested_cc_winding.svg
new file mode 100644
index 00000000..c04504ff
--- /dev/null
+++ b/inst/tinytest/_tinysnapshot/polypath_nested_cc_winding.svg
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' class='svglite' width='504.00pt' height='504.00pt' viewBox='0 0 504.00 504.00'>
+<defs>
+  <style type='text/css'><![CDATA[
+    .svglite line, .svglite polyline, .svglite polygon, .svglite path, .svglite rect, .svglite circle {
+      fill: none;
+      stroke: #000000;
+      stroke-linecap: round;
+      stroke-linejoin: round;
+      stroke-miterlimit: 10.00;
+    }
+    .svglite text {
+      white-space: pre;
+    }
+  ]]></style>
+</defs>
+<rect width='100%' height='100%' style='stroke: none; fill: #FFFFFF;'/>
+<defs>
+  <clipPath id='cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA='>
+    <rect x='0.00' y='0.00' width='504.00' height='504.00' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='34.47' text-anchor='middle' style='font-size: 14.40px; font-weight: bold; font-family: "Liberation Sans";' textLength='235.17px' lengthAdjust='spacingAndGlyphs'>Nested rectangles, both clockwise</text>
+</g>
+<defs>
+  <clipPath id='cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng=='>
+    <rect x='59.04' y='59.04' width='414.72' height='371.52' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng==)'>
+<path d='M 74.40 416.80 L 74.40 72.80 L 458.40 72.80 L 458.40 416.80 ZM 122.40 373.80 L 122.40 115.80 L 410.40 115.80 L 410.40 373.80 Z' style='fill-rule: nonzero; fill: #BEBEBE; stroke-width: 0.75;' />
+</g>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='56.16' text-anchor='middle' style='font-size: 12.00px; font-family: "Liberation Sans";' textLength='68.71px' lengthAdjust='spacingAndGlyphs'>Rule:winding</text>
+</g>
+</svg>
diff --git a/inst/tinytest/_tinysnapshot/polypath_overlapping_ca_evenodd.svg b/inst/tinytest/_tinysnapshot/polypath_overlapping_ca_evenodd.svg
new file mode 100644
index 00000000..fcbbcd9f
--- /dev/null
+++ b/inst/tinytest/_tinysnapshot/polypath_overlapping_ca_evenodd.svg
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' class='svglite' width='504.00pt' height='504.00pt' viewBox='0 0 504.00 504.00'>
+<defs>
+  <style type='text/css'><![CDATA[
+    .svglite line, .svglite polyline, .svglite polygon, .svglite path, .svglite rect, .svglite circle {
+      fill: none;
+      stroke: #000000;
+      stroke-linecap: round;
+      stroke-linejoin: round;
+      stroke-miterlimit: 10.00;
+    }
+    .svglite text {
+      white-space: pre;
+    }
+  ]]></style>
+</defs>
+<rect width='100%' height='100%' style='stroke: none; fill: #FFFFFF;'/>
+<defs>
+  <clipPath id='cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA='>
+    <rect x='0.00' y='0.00' width='504.00' height='504.00' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='34.47' text-anchor='middle' style='font-size: 14.40px; font-weight: bold; font-family: "Liberation Sans";' textLength='411.93px' lengthAdjust='spacingAndGlyphs'>Overlapping rectangles, one clockwise, other anti-clockwise</text>
+</g>
+<defs>
+  <clipPath id='cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng=='>
+    <rect x='59.04' y='59.04' width='414.72' height='371.52' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng==)'>
+<path d='M 74.40 416.80 L 74.40 201.80 L 314.40 201.80 L 314.40 416.80 ZM 218.40 287.80 L 458.40 287.80 L 458.40 72.80 L 218.40 72.80 Z' style='fill-rule: evenodd; fill: #BEBEBE; stroke-width: 0.75;' />
+</g>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='56.16' text-anchor='middle' style='font-size: 12.00px; font-family: "Liberation Sans";' textLength='74.07px' lengthAdjust='spacingAndGlyphs'>Rule:evenodd</text>
+</g>
+</svg>
diff --git a/inst/tinytest/_tinysnapshot/polypath_overlapping_ca_winding.svg b/inst/tinytest/_tinysnapshot/polypath_overlapping_ca_winding.svg
new file mode 100644
index 00000000..e4bed446
--- /dev/null
+++ b/inst/tinytest/_tinysnapshot/polypath_overlapping_ca_winding.svg
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' class='svglite' width='504.00pt' height='504.00pt' viewBox='0 0 504.00 504.00'>
+<defs>
+  <style type='text/css'><![CDATA[
+    .svglite line, .svglite polyline, .svglite polygon, .svglite path, .svglite rect, .svglite circle {
+      fill: none;
+      stroke: #000000;
+      stroke-linecap: round;
+      stroke-linejoin: round;
+      stroke-miterlimit: 10.00;
+    }
+    .svglite text {
+      white-space: pre;
+    }
+  ]]></style>
+</defs>
+<rect width='100%' height='100%' style='stroke: none; fill: #FFFFFF;'/>
+<defs>
+  <clipPath id='cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA='>
+    <rect x='0.00' y='0.00' width='504.00' height='504.00' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='34.47' text-anchor='middle' style='font-size: 14.40px; font-weight: bold; font-family: "Liberation Sans";' textLength='411.93px' lengthAdjust='spacingAndGlyphs'>Overlapping rectangles, one clockwise, other anti-clockwise</text>
+</g>
+<defs>
+  <clipPath id='cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng=='>
+    <rect x='59.04' y='59.04' width='414.72' height='371.52' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng==)'>
+<path d='M 74.40 416.80 L 74.40 201.80 L 314.40 201.80 L 314.40 416.80 ZM 218.40 287.80 L 458.40 287.80 L 458.40 72.80 L 218.40 72.80 Z' style='fill-rule: nonzero; fill: #BEBEBE; stroke-width: 0.75;' />
+</g>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='56.16' text-anchor='middle' style='font-size: 12.00px; font-family: "Liberation Sans";' textLength='68.71px' lengthAdjust='spacingAndGlyphs'>Rule:winding</text>
+</g>
+</svg>
diff --git a/inst/tinytest/_tinysnapshot/polypath_overlapping_cc_evenodd.svg b/inst/tinytest/_tinysnapshot/polypath_overlapping_cc_evenodd.svg
new file mode 100644
index 00000000..41f03a4c
--- /dev/null
+++ b/inst/tinytest/_tinysnapshot/polypath_overlapping_cc_evenodd.svg
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' class='svglite' width='504.00pt' height='504.00pt' viewBox='0 0 504.00 504.00'>
+<defs>
+  <style type='text/css'><![CDATA[
+    .svglite line, .svglite polyline, .svglite polygon, .svglite path, .svglite rect, .svglite circle {
+      fill: none;
+      stroke: #000000;
+      stroke-linecap: round;
+      stroke-linejoin: round;
+      stroke-miterlimit: 10.00;
+    }
+    .svglite text {
+      white-space: pre;
+    }
+  ]]></style>
+</defs>
+<rect width='100%' height='100%' style='stroke: none; fill: #FFFFFF;'/>
+<defs>
+  <clipPath id='cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA='>
+    <rect x='0.00' y='0.00' width='504.00' height='504.00' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='34.47' text-anchor='middle' style='font-size: 14.40px; font-weight: bold; font-family: "Liberation Sans";' textLength='271.14px' lengthAdjust='spacingAndGlyphs'>Overlapping rectangles, both clockwise</text>
+</g>
+<defs>
+  <clipPath id='cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng=='>
+    <rect x='59.04' y='59.04' width='414.72' height='371.52' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng==)'>
+<path d='M 74.40 416.80 L 74.40 201.80 L 314.40 201.80 L 314.40 416.80 ZM 218.40 287.80 L 218.40 72.80 L 458.40 72.80 L 458.40 287.80 Z' style='fill-rule: evenodd; fill: #BEBEBE; stroke-width: 0.75;' />
+</g>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='56.16' text-anchor='middle' style='font-size: 12.00px; font-family: "Liberation Sans";' textLength='74.07px' lengthAdjust='spacingAndGlyphs'>Rule:evenodd</text>
+</g>
+</svg>
diff --git a/inst/tinytest/_tinysnapshot/polypath_overlapping_cc_winding.svg b/inst/tinytest/_tinysnapshot/polypath_overlapping_cc_winding.svg
new file mode 100644
index 00000000..57265c2c
--- /dev/null
+++ b/inst/tinytest/_tinysnapshot/polypath_overlapping_cc_winding.svg
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' class='svglite' width='504.00pt' height='504.00pt' viewBox='0 0 504.00 504.00'>
+<defs>
+  <style type='text/css'><![CDATA[
+    .svglite line, .svglite polyline, .svglite polygon, .svglite path, .svglite rect, .svglite circle {
+      fill: none;
+      stroke: #000000;
+      stroke-linecap: round;
+      stroke-linejoin: round;
+      stroke-miterlimit: 10.00;
+    }
+    .svglite text {
+      white-space: pre;
+    }
+  ]]></style>
+</defs>
+<rect width='100%' height='100%' style='stroke: none; fill: #FFFFFF;'/>
+<defs>
+  <clipPath id='cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA='>
+    <rect x='0.00' y='0.00' width='504.00' height='504.00' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='34.47' text-anchor='middle' style='font-size: 14.40px; font-weight: bold; font-family: "Liberation Sans";' textLength='271.14px' lengthAdjust='spacingAndGlyphs'>Overlapping rectangles, both clockwise</text>
+</g>
+<defs>
+  <clipPath id='cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng=='>
+    <rect x='59.04' y='59.04' width='414.72' height='371.52' />
+  </clipPath>
+</defs>
+<g clip-path='url(#cpNTkuMDR8NDczLjc2fDU5LjA0fDQzMC41Ng==)'>
+<path d='M 74.40 416.80 L 74.40 201.80 L 314.40 201.80 L 314.40 416.80 ZM 218.40 287.80 L 218.40 72.80 L 458.40 72.80 L 458.40 287.80 Z' style='fill-rule: nonzero; fill: #BEBEBE; stroke-width: 0.75;' />
+</g>
+<g clip-path='url(#cpMC4wMHw1MDQuMDB8MC4wMHw1MDQuMDA=)'>
+<text x='266.40' y='56.16' text-anchor='middle' style='font-size: 12.00px; font-family: "Liberation Sans";' textLength='68.71px' lengthAdjust='spacingAndGlyphs'>Rule:winding</text>
+</g>
+</svg>
diff --git a/inst/tinytest/test-polygon.R b/inst/tinytest/test-polygon.R
index f4de6ee6..728bb97a 100644
--- a/inst/tinytest/test-polygon.R
+++ b/inst/tinytest/test-polygon.R
@@ -14,3 +14,85 @@ f = function() {
   )
 }
 expect_snapshot_plot(f, label = "polygon_heart")
+
+#
+## polygon path
+ 
+# (Note: these tests adapted from the ?polypath examples) 
+
+for (rrule in c("winding", "evenodd")) {
+  
+  f = function() {
+    plt(
+      c(.1, .1, .9, .9, NA, .2, .2, .8, .8),
+      c(.1, .9, .9, .1, NA, .2, .8, .8, .2),
+      main = "Nested rectangles, both clockwise",
+      type = "polypath",
+      rule = rrule,
+      fill = "grey",
+      axes = FALSE, xlab = NA, ylab = NA
+    )
+    mtext(paste0("Rule:", rrule))
+  }
+  expect_snapshot_plot(f, label = paste0("polypath_nested_cc_", rrule))
+  
+  f = function() {
+    plt(
+      c(.1, .1, .9, .9, NA, .2, .8, .8, .2),
+      c(.1, .9, .9, .1, NA, .2, .2, .8, .8),
+      main = "Nested rectangles, outer clockwise, inner anti-clockwise",
+      type = "polypath",
+      rule = rrule,
+      fill = "grey",
+      axes = FALSE, xlab = NA, ylab = NA
+    )
+    mtext(paste0("Rule:", rrule))
+  }
+  expect_snapshot_plot(f, label = paste0("polypath_nested_ca_", rrule))
+  
+  f = function() {
+    plt(
+      c(.1, .1, .4, .4, NA, .6, .9, .9, .6),
+      c(.1, .4, .4, .1, NA, .6, .6, .9, .9),
+      main = "Disjoint rectangles",
+      type = "polypath",
+      rule = rrule,
+      fill = "grey",
+      axes = FALSE, xlab = NA, ylab = NA
+    )
+    mtext(paste0("Rule:", rrule))
+  }
+  expect_snapshot_plot(f, label = paste0("polypath_disjoint_", rrule))
+  
+  f = function() {
+    plt(
+      c(.1, .1, .6, .6, NA, .4, .4, .9, .9),
+      c(.1, .6, .6, .1, NA, .4, .9, .9, .4),
+      main = "Overlapping rectangles, both clockwise",
+      type = "polypath",
+      rule = rrule,
+      fill = "grey",
+      axes = FALSE, xlab = NA, ylab = NA
+    )
+    mtext(paste0("Rule:", rrule))
+  }
+  expect_snapshot_plot(f, label = paste0("polypath_overlapping_cc_", rrule))
+  
+  f = function() {
+    plt(
+      c(.1, .1, .6, .6, NA, .4, .9, .9, .4),
+      c(.1, .6, .6, .1, NA, .4, .4, .9, .9),
+      main = "Overlapping rectangles, one clockwise, other anti-clockwise",
+      type = "polypath",
+      rule = rrule,
+      fill = "grey",
+      axes = FALSE, xlab = NA, ylab = NA
+    )
+    mtext(paste0("Rule:", rrule))
+  }
+  expect_snapshot_plot(f, label = paste0("polypath_overlapping_ca_", rrule))
+  
+  
+}
+rm(rrule)
+
diff --git a/man/tinyplot.Rd b/man/tinyplot.Rd
index dcceaec9..c0f0eebe 100644
--- a/man/tinyplot.Rd
+++ b/man/tinyplot.Rd
@@ -186,10 +186,10 @@ lines, "o" for overplotted points and lines, "s" and "S" for stair steps,
 and "h" for histogram-like vertical lines. Specifying "n" produces an empty
 plot over the extent of the data, but with no internal elements.
 \item Additional tinyplot types: "boxplot" for boxplots, "density" for
-densities,  "pointrange" or "errorbar" for segment intervals, and
-"polygon", "ribbon" or "area" for polygon intervals (where area plots are a
-special case of ribbon plots with \code{ymin} set to 0 and \code{ymax} set to \code{y};
-see below).
+densities, "polygon" or "polypath" for polygons,  "pointrange" or"errorbar"
+for segment intervals, and "ribbon" or "area" for polygon intervals (where
+area plots are a special case of ribbon plots with \code{ymin} set to 0 and
+\code{ymax} set to \code{y}; see below).
 }}
 
 \item{xlim}{the x limits (x1, x2) of the plot. Note that x1 > x2 is allowed
