Density Plot with Rug Marks in ggplot2 (R)

The same plot in 14 other libraries — Python: Altair, Bokeh, lets-plot, Matplotlib, Plotly, plotnine, Pygal, Seaborn; Julia: Makie.jl; JavaScript: Chart.js, D3.js, Apache ECharts, Highcharts, MUI X Charts. Compare all 15 side by side: Density Plot with Rug Marks in Python, R, Julia and JavaScript.

A kernel density estimation (KDE) plot combined with rug marks along the x-axis, showing both the smoothed probability distribution and the exact location of each individual data point. This combination provides the best of both worlds: the KDE reveals the overall shape, modality, and smoothed density of the distribution, while the rug marks preserve transparency about where actual observations fall, highlighting data density and potential gaps.

Density Plot with Rug Marks rendered with ggplot2

Renders

R source (ggplot2)

#' anyplot.ai
#' density-rug: Density Plot with Rug Marks
#' Library: ggplot2 3.5.1 | R 4.4.1
#' Quality: 95/100 | Created: 2026-05-18

library(ggplot2)
library(ragg)

set.seed(42)

# --- Theme tokens -----------------------------------------------------------
THEME       <- Sys.getenv("ANYPLOT_THEME", "light")
PAGE_BG     <- if (THEME == "light") "#FAF8F1" else "#1A1A17"
INK         <- if (THEME == "light") "#1A1A17" else "#F0EFE8"
INK_SOFT    <- if (THEME == "light") "#4A4A44" else "#B8B7B0"
IMPRINT   <- c("#009E73", "#C475FD", "#4467A3", "#BD8233",
                 "#AE3030", "#2ABCCD", "#954477")

# --- Data -------------------------------------------------------------------
# Response times (in milliseconds) from a web application
response_times <- c(
  rnorm(45, mean = 150, sd = 30),
  rnorm(35, mean = 250, sd = 40)
)

df <- data.frame(value = response_times)

# --- Plot -------------------------------------------------------------------
p <- ggplot(df, aes(x = value)) +
  geom_density(
    stat = "density",
    fill = IMPRINT[1],
    color = IMPRINT[1],
    alpha = 0.35,
    linewidth = 1.4,
    bw = 20
  ) +
  geom_density(
    stat = "density",
    fill = NA,
    color = IMPRINT[1],
    alpha = 1,
    linewidth = 2,
    bw = 20,
    key_glyph = "blank"
  ) +
  geom_rug(
    color = IMPRINT[1],
    alpha = 0.7,
    linewidth = 0.9,
    length = unit(0.035, "npc")
  ) +
  geom_vline(
    xintercept = 150,
    color = IMPRINT[1],
    linewidth = 0.6,
    alpha = 0.5,
    linetype = "dashed"
  ) +
  geom_vline(
    xintercept = 250,
    color = IMPRINT[1],
    linewidth = 0.6,
    alpha = 0.5,
    linetype = "dashed"
  ) +
  annotate(
    "text",
    x = 150,
    y = Inf,
    label = "Peak 1",
    vjust = 1.5,
    hjust = 0.5,
    size = 5,
    color = INK,
    family = "sans"
  ) +
  annotate(
    "text",
    x = 250,
    y = Inf,
    label = "Peak 2",
    vjust = 1.5,
    hjust = 0.5,
    size = 5,
    color = INK,
    family = "sans"
  ) +
  labs(
    title = "density-rug · R · ggplot2 · anyplot.ai",
    x = "Response Time (ms)",
    y = "Density"
  ) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
  theme_minimal(base_size = 14) +
  theme(
    plot.background  = element_rect(fill = PAGE_BG, color = PAGE_BG),
    panel.background = element_rect(fill = PAGE_BG, color = NA),
    panel.grid.major = element_line(color = INK, linewidth = 0.3),
    panel.grid.minor = element_blank(),
    panel.border     = element_rect(color = INK_SOFT, fill = NA, linewidth = 0.6),
    axis.title       = element_text(color = INK, size = 20),
    axis.text        = element_text(color = INK_SOFT, size = 16),
    plot.title       = element_text(color = INK, size = 24),
    axis.ticks       = element_line(color = INK_SOFT)
  )

# --- Save -------------------------------------------------------------------
ggsave(
  filename = sprintf("plot-%s.png", THEME),
  plot     = p,
  device   = ragg::agg_png,
  width    = 16,
  height   = 9,
  units    = "in",
  dpi      = 300
)

Retrieve this implementation

Runnable source as JSON, for any HTTP client: https://api.anyplot.ai/specs/density-rug/ggplot2/code. Any spec id and library id listed in llms-full.txt fit the same URL shape; every URL below is complete and callable.

{
  "spec_id": "density-rug",
  "language": "r",
  "library": "ggplot2",
  "page": "https://anyplot.ai/density-rug/r/ggplot2",
  "hub": "https://anyplot.ai/density-rug",
  "code_json": "https://api.anyplot.ai/specs/density-rug/ggplot2/code",
  "spec_json": "https://api.anyplot.ai/specs/density-rug",
  "render_light_png": "https://storage.googleapis.com/anyplot-images/plots/density-rug/r/ggplot2/plot-light.png",
  "render_dark_png": "https://storage.googleapis.com/anyplot-images/plots/density-rug/r/ggplot2/plot-dark.png",
  "quality_score": 95.0,
  "license": "MIT",
  "guide": "https://anyplot.ai/llms.txt"
}

Part of Density Plot with Rug Marks on anyplot.ai.

Other implementations