Basic Density Plot — plotnine

A density plot (also known as Kernel Density Estimation or KDE plot) visualizes the distribution of a continuous variable by smoothing the data into a continuous probability density curve. Unlike histograms which use discrete bins, density plots provide a smooth representation of the underlying distribution, making it easier to identify patterns such as skewness, modality, and overall shape.

Basic Density Plot rendered with plotnine

Python source (plotnine)

""" anyplot.ai
density-basic: Basic Density Plot
Library: plotnine 0.15.4 | Python 3.13.13
Quality: 90/100 | Updated: 2026-05-30
"""

import os
import sys


# Remove script dir from sys.path to avoid shadowing the plotnine package
_script_dir = os.path.dirname(os.path.abspath(__file__))
for _p in [_script_dir, "", "."]:
    while _p in sys.path:
        sys.path.remove(_p)

import numpy as np
import pandas as pd
from plotnine import (
    aes,
    after_stat,
    annotate,
    coord_cartesian,
    element_blank,
    element_line,
    element_rect,
    element_text,
    geom_area,
    geom_line,
    geom_rug,
    geom_vline,
    ggplot,
    labs,
    scale_x_continuous,
    scale_y_continuous,
    theme,
    theme_minimal,
)


# Theme tokens (Imprint palette — see prompts/default-style-guide.md)
THEME = os.getenv("ANYPLOT_THEME", "light")
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F"
BRAND = "#009E73"  # Imprint position 1 — always first series

# Data — bimodal test score distribution (150 main + 50 high achievers)
np.random.seed(42)
test_scores = np.concatenate([np.random.normal(72, 10, 150), np.random.normal(88, 5, 50)])
test_scores = np.clip(test_scores, 0, 100)

df = pd.DataFrame({"score": test_scores})

# Title with length-aware font sizing
title = "density-basic · python · plotnine · anyplot.ai"
n = len(title)
ratio = 67 / n if n > 67 else 1.0
title_fs = max(8, round(12 * ratio))

# Plot — layered density with bimodal emphasis
plot = (
    ggplot(df, aes(x="score"))
    + geom_area(aes(y=after_stat("density")), stat="density", fill=BRAND, alpha=0.3, color="none")
    + geom_line(aes(y=after_stat("density")), stat="density", color=BRAND, size=1.8)
    + geom_vline(xintercept=72, linetype="dashed", color=INK_SOFT, size=0.9, alpha=0.75)
    + geom_vline(xintercept=88, linetype="dashed", color=INK_SOFT, size=0.9, alpha=0.75)
    + geom_rug(color=INK_MUTED, alpha=0.5, size=0.6)
    + annotate("text", x=72, y=0.034, label="Main Group (μ ≈ 72)", size=3.5, color=INK)
    + annotate("text", x=89, y=0.029, label="High Achievers (μ ≈ 88)", size=3.5, color=INK)
    + labs(x="Test Score (points)", y="Probability Density", title=title)
    + scale_x_continuous(breaks=range(45, 101, 10))
    + scale_y_continuous(expand=(0, 0, 0.2, 0))
    + coord_cartesian(xlim=(45, 102))
    + theme_minimal()
    + theme(
        figure_size=(8, 4.5),
        text=element_text(size=7, color=INK_SOFT),
        axis_title=element_text(size=10, color=INK),
        axis_text=element_text(size=8, color=INK_SOFT),
        plot_title=element_text(size=title_fs, color=INK),
        legend_text=element_text(size=8, color=INK_SOFT),
        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),
        panel_background=element_rect(fill=PAGE_BG),
        panel_grid_major_x=element_blank(),
        panel_grid_minor=element_blank(),
        panel_grid_major_y=element_line(color=INK, size=0.3, alpha=0.15),
        panel_border=element_blank(),
        axis_line=element_line(color=INK_SOFT),
    )
)

# Save
plot.save(f"plot-{THEME}.png", dpi=400, width=8, height=4.5, units="in", verbose=False)

Part of Basic Density Plot on anyplot.ai.

Other implementations