{"spec_id":"depth-order-book","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\ndepth-order-book: Order Book Depth Chart\nLibrary: matplotlib 3.11.0 | Python 3.13.13\nQuality: 89/100 | Created: 2026-06-15\n\"\"\"\n\nimport os\n\nimport matplotlib.patches as mpatches\nimport matplotlib.pyplot as plt\nimport matplotlib.ticker as mticker\nimport numpy as np\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\n# Imprint palette — semantic mapping: buy=green (pos 1), sell=red (pos 5)\nBID_COLOR = \"#009E73\"  # Imprint position 1 — bids / buy side\nASK_COLOR = \"#AE3030\"  # Imprint position 5 — asks / sell side (semantic: loss/sell)\n\n# Data — synthetic BTC/USD order book snapshot\nnp.random.seed(42)\nMID_PRICE = 60_000.0\nSPREAD = 10.0  # $10 bid-ask spread\nBEST_BID = MID_PRICE - SPREAD / 2  # 59995\nBEST_ASK = MID_PRICE + SPREAD / 2  # 60005\nN_LEVELS = 50\nTICK = 5.0  # $5 price tick spacing\n\n# Bid side: prices descend from BEST_BID outward (index 0 = best bid)\nbid_prices = BEST_BID - np.arange(N_LEVELS) * TICK\nbid_qty = np.abs(np.random.normal(2.0, 0.8, N_LEVELS))\nbid_qty += 0.05 * np.arange(N_LEVELS)  # modest growth toward worse prices\nbid_qty[18] += 12.0  # support wall at ~$59,905\nbid_qty[35] += 18.0  # major support wall at ~$59,820\nbid_cum = np.cumsum(bid_qty)\n\n# Ask side: prices ascend from BEST_ASK outward (index 0 = best ask)\nask_prices = BEST_ASK + np.arange(N_LEVELS) * TICK\nask_qty = np.abs(np.random.normal(1.8, 0.9, N_LEVELS))\nask_qty += 0.04 * np.arange(N_LEVELS)\nask_qty[22] += 15.0  # resistance wall at ~$60,115\nask_cum = np.cumsum(ask_qty)\n\n# Step chart data — both sides in ascending price order (left to right)\n# A 0.1 USD epsilon point inside the spread creates a clean vertical wall\n# at the best bid/ask without being visible at chart scale (~$250 range).\nBID_WALL = BEST_BID + 0.1\nASK_WALL = BEST_ASK - 0.1\n\nbid_x = np.append(bid_prices[::-1], BID_WALL)\nbid_y = np.append(bid_cum[::-1], 0.0)\n\nask_x = np.concatenate([[ASK_WALL], ask_prices])\nask_y = np.concatenate([[0.0], ask_cum])\n\n# Plot\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Bid area — descending staircase from left toward mid price\nax.fill_between(bid_x, bid_y, step=\"post\", color=BID_COLOR, alpha=0.2)\nax.fill_between(bid_x, bid_y, step=\"post\", facecolor=\"none\", edgecolor=BID_COLOR, linewidth=0.5, hatch=\"\\\\\\\\\")\nax.step(bid_x, bid_y, where=\"post\", color=BID_COLOR, linewidth=2.0)\n\n# Ask area — ascending staircase from mid price toward right\nax.fill_between(ask_x, ask_y, step=\"post\", color=ASK_COLOR, alpha=0.2)\nax.fill_between(ask_x, ask_y, step=\"post\", facecolor=\"none\", edgecolor=ASK_COLOR, linewidth=0.5, hatch=\"////\")\nax.step(ask_x, ask_y, where=\"post\", color=ASK_COLOR, linewidth=2.0)\n\n# Mid price dashed vertical line\nax.axvline(MID_PRICE, color=INK_MUTED, linewidth=1.0, linestyle=\"--\", alpha=0.7, zorder=5)\n\n# Mid price annotation\ny_top = max(bid_cum[-1], ask_cum[-1])\nax.annotate(\n    f\"Mid ${MID_PRICE:,.0f}\\nSpread ${SPREAD:.0f}\",\n    xy=(MID_PRICE + 25, y_top * 0.45),\n    fontsize=7.5,\n    color=INK_MUTED,\n    ha=\"left\",\n    va=\"center\",\n    bbox={\"facecolor\": ELEVATED_BG, \"edgecolor\": INK_SOFT, \"alpha\": 0.9, \"boxstyle\": \"round,pad=0.35\"},\n)\n\n# Style\ntitle = \"BTC/USD Order Book · depth-order-book · python · matplotlib · anyplot.ai\"\nn = len(title)\ntitle_fontsize = max(8, round(12 * 67 / n)) if n > 67 else 12\n\nax.set_title(title, fontsize=title_fontsize, fontweight=\"medium\", color=INK, pad=10)\nax.set_xlabel(\"Price (USD)\", fontsize=10, color=INK, labelpad=6)\nax.set_ylabel(\"Cumulative Volume (BTC)\", fontsize=10, color=INK, labelpad=6)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT, labelcolor=INK_SOFT)\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nfor spine in (\"left\", \"bottom\"):\n    ax.spines[spine].set_color(INK_SOFT)\n\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)\nax.set_ylim(bottom=0)\n\n# Center the x-axis on mid price with balanced wings\nwing = N_LEVELS * TICK * 1.05\nax.set_xlim(MID_PRICE - wing, MID_PRICE + wing)\nax.xaxis.set_major_formatter(mticker.FuncFormatter(lambda x, _: f\"${x:,.0f}\"))\nplt.setp(ax.get_xticklabels(), rotation=30, ha=\"right\")\n\n# Legend\nbid_patch = mpatches.Patch(facecolor=BID_COLOR, edgecolor=BID_COLOR, alpha=0.7, hatch=\"\\\\\\\\\", label=\"Bids (Buy)\")\nask_patch = mpatches.Patch(facecolor=ASK_COLOR, edgecolor=ASK_COLOR, alpha=0.7, hatch=\"////\", label=\"Asks (Sell)\")\nleg = ax.legend(\n    handles=[bid_patch, ask_patch], fontsize=8, loc=\"upper center\", ncol=2, framealpha=0.9, bbox_to_anchor=(0.5, 0.97)\n)\nleg.get_frame().set_facecolor(ELEVATED_BG)\nleg.get_frame().set_edgecolor(INK_SOFT)\nplt.setp(leg.get_texts(), color=INK_SOFT)\n\nfig.subplots_adjust(left=0.09, right=0.97, top=0.91, bottom=0.14)\n\n# Save\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\nplt.close()\n"}