A market depth chart visualizes a snapshot of an exchange order book as two cumulative step areas around the mid price. Cumulative bid volume rises as a green step area to the left of the mid price (summing buy orders from the best bid downward), while cumulative ask volume rises as a red step area to the right (summing sell orders from the best ask upward). The bid-ask spread appears as a gap at the center, with price on the x-axis and cumulative quantity on the y-axis. This is the iconic chart found in nearly every trading and crypto exchange UI, revealing liquidity, support/resistance walls, and the imbalance between buying and selling pressure.

""" anyplot.ai
depth-order-book: Order Book Depth Chart
Library: seaborn 0.13.2 | Python 3.13.13
Quality: 88/100 | Created: 2026-06-15
"""
import os
import sys
# Remove this script's directory from sys.path so 'import seaborn' finds the installed
# library rather than this file (Python adds the script dir to sys.path[0] automatically)
_script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path = [p for p in sys.path if os.path.abspath(p or ".") != _script_dir]
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as np
import seaborn as sns
# Theme tokens
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"
# Semantic colors — bid=green (buy/bullish), ask=red (sell/bearish)
BID_COLOR = "#009E73" # Imprint palette position 1, brand green — buy side
ASK_COLOR = "#AE3030" # Imprint palette position 5, matte red — sell side
sns.set_theme(
style="ticks",
rc={
"figure.facecolor": PAGE_BG,
"axes.facecolor": PAGE_BG,
"axes.edgecolor": INK_SOFT,
"axes.labelcolor": INK,
"text.color": INK,
"xtick.color": INK_SOFT,
"ytick.color": INK_SOFT,
"grid.color": INK,
"grid.alpha": 0.15,
"legend.facecolor": ELEVATED_BG,
"legend.edgecolor": INK_SOFT,
},
)
# Data — BTC/USD order book snapshot (synthetic)
np.random.seed(42)
mid_price = 60_000.0
spread = 10.0 # $10 bid-ask spread
best_bid = mid_price - spread / 2 # 59995.0
best_ask = mid_price + spread / 2 # 60005.0
n_levels = 40
tick = 5.0 # $5 per price level
# Bid levels: descending from best_bid (index 0 = best bid, index 39 = worst bid)
bid_prices = best_bid - tick * np.arange(n_levels)
bid_qty = np.abs(np.random.normal(2.0, 1.0, n_levels))
bid_qty[14:17] += 16.0 # support wall at ~59925
bid_cum = np.cumsum(bid_qty)
# Ask levels: ascending from best_ask (index 0 = best ask, index 39 = worst ask)
ask_prices = best_ask + tick * np.arange(n_levels)
ask_qty = np.abs(np.random.normal(2.0, 1.0, n_levels))
ask_qty[17:20] += 20.0 # resistance wall at ~60090
ask_cum = np.cumsum(ask_qty)
# Bid sorted ascending for left-to-right staircase rendering
bid_x = bid_prices[::-1] # [59800, ..., 59995]
bid_y = bid_cum[::-1] # [total_cum, ..., min_cum]
# Plot
fig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)
ax.set_facecolor(PAGE_BG)
# Dark mode: raise fill alpha so areas remain visible against near-black background
FILL_ALPHA = 0.22 if THEME == "light" else 0.35
# Bid area: semi-transparent fill + solid step outline via seaborn lineplot
ax.fill_between(bid_x, bid_y, step="post", alpha=FILL_ALPHA, color=BID_COLOR)
sns.lineplot(x=bid_x, y=bid_y, drawstyle="steps-post", ax=ax, color=BID_COLOR, linewidth=1.8, label="Bids (Buy)")
# Ask area: semi-transparent fill + solid step outline via seaborn lineplot
ax.fill_between(ask_prices, ask_cum, step="post", alpha=FILL_ALPHA, color=ASK_COLOR)
sns.lineplot(
x=ask_prices, y=ask_cum, drawstyle="steps-post", ax=ax, color=ASK_COLOR, linewidth=1.8, label="Asks (Sell)"
)
# Mid price dashed vertical line
ax.axvline(mid_price, color=INK_SOFT, linestyle="--", linewidth=1.0, alpha=0.7)
# Annotate mid price and spread
y_top = max(bid_y.max(), ask_cum.max())
ax.annotate(
f"Mid: ${mid_price:,.0f}\nSpread: ${spread:.0f}",
xy=(mid_price, y_top * 0.80),
ha="center",
va="top",
fontsize=8,
color=INK_MUTED,
bbox={"boxstyle": "round,pad=0.4", "facecolor": ELEVATED_BG, "edgecolor": INK_SOFT, "linewidth": 0.8, "alpha": 0.9},
)
# Style
title = "depth-order-book · python · seaborn · anyplot.ai"
ax.set_title(title, fontsize=12, fontweight="medium", color=INK, pad=10)
ax.set_xlabel("Price (USD)", fontsize=10, color=INK, labelpad=6)
ax.set_ylabel("Cumulative Volume (BTC)", fontsize=10, color=INK, labelpad=6)
ax.tick_params(axis="both", labelsize=8, colors=INK_SOFT)
ax.xaxis.set_major_formatter(mticker.FuncFormatter(lambda x, _: f"${x:,.0f}"))
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["left"].set_color(INK_SOFT)
ax.spines["bottom"].set_color(INK_SOFT)
ax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)
ax.set_ylim(bottom=0)
legend = ax.legend(fontsize=8, framealpha=0.9, facecolor=ELEVATED_BG, edgecolor=INK_SOFT)
for text in legend.get_texts():
text.set_color(INK_SOFT)
fig.subplots_adjust(left=0.10, right=0.97, top=0.92, bottom=0.13)
# Save to the script's own directory (no bbox_inches='tight' — see seaborn library guide)
plt.savefig(os.path.join(_script_dir, f"plot-{THEME}.png"), dpi=400, facecolor=PAGE_BG)
plt.close()
Part of Order Book Depth Chart on anyplot.ai.