{"spec_id":"ohlc-bar","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nohlc-bar: OHLC Bar Chart\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-17\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\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\"\n\n# OHLC-specific colors: up bars and down bars\nCOLOR_UP = \"#306998\"\nCOLOR_DOWN = \"#C44E52\"\n\n# Set seaborn theme with theme-adaptive styling\nsns.set_theme(\n    style=\"ticks\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": PAGE_BG,\n        \"axes.edgecolor\": INK_SOFT,\n        \"axes.labelcolor\": INK,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n        \"grid.color\": INK,\n        \"grid.alpha\": 0.10,\n        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\n# Generate synthetic OHLC stock data\nnp.random.seed(42)\nn_days = 45\n\n# Create date range (business days)\ndates = pd.date_range(start=\"2024-01-02\", periods=n_days, freq=\"B\")\n\n# Generate realistic price movements\nbase_price = 150.0\nreturns = np.random.normal(0.001, 0.02, n_days)\nclose_prices = base_price * np.cumprod(1 + returns)\n\n# Generate OHLC from close prices\nopen_prices = np.roll(close_prices, 1)\nopen_prices[0] = base_price\nhigh_prices = np.maximum(open_prices, close_prices) * (1 + np.abs(np.random.normal(0, 0.01, n_days)))\nlow_prices = np.minimum(open_prices, close_prices) * (1 - np.abs(np.random.normal(0, 0.01, n_days)))\n\n# Create DataFrame\ndf = pd.DataFrame({\"date\": dates, \"open\": open_prices, \"high\": high_prices, \"low\": low_prices, \"close\": close_prices})\n\n# Add direction column for coloring\ndf[\"direction\"] = np.where(df[\"close\"] >= df[\"open\"], \"up\", \"down\")\n\n# Create figure\nfig, ax = plt.subplots(figsize=(16, 9), facecolor=PAGE_BG)\n\n# Draw OHLC bars using matplotlib primitives\ntick_width = 0.4\n\nfor idx, row in df.iterrows():\n    i = df.index.get_loc(idx)\n    color = COLOR_UP if row[\"direction\"] == \"up\" else COLOR_DOWN\n\n    # Vertical line from low to high\n    ax.vlines(x=i, ymin=row[\"low\"], ymax=row[\"high\"], color=color, linewidth=2)\n\n    # Left tick for open price\n    ax.hlines(y=row[\"open\"], xmin=i - tick_width, xmax=i, color=color, linewidth=2)\n\n    # Right tick for close price\n    ax.hlines(y=row[\"close\"], xmin=i, xmax=i + tick_width, color=color, linewidth=2)\n\n# Create custom legend with line representations\nup_line = plt.Line2D([0], [0], color=COLOR_UP, linewidth=2.5, label=\"Up (Close ≥ Open)\")\ndown_line = plt.Line2D([0], [0], color=COLOR_DOWN, linewidth=2.5, label=\"Down (Close < Open)\")\nax.legend(handles=[up_line, down_line], fontsize=16, loc=\"upper left\")\n\n# Configure x-axis with date labels\ntick_positions = np.arange(0, len(df), max(1, len(df) // 8))\ntick_labels = [df[\"date\"].iloc[i].strftime(\"%b %d\") for i in tick_positions]\nax.set_xticks(tick_positions)\nax.set_xticklabels(tick_labels, rotation=45, ha=\"right\", fontsize=16)\n\n# Style the plot\nax.set_xlabel(\"Date\", fontsize=20, color=INK)\nax.set_ylabel(\"Price ($)\", fontsize=20, color=INK)\nax.set_title(\"ohlc-bar · seaborn · anyplot.ai\", fontsize=24, color=INK)\nax.tick_params(axis=\"both\", labelsize=16, colors=INK_SOFT)\n\n# Remove top and right spines\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\n\n# Subtle grid\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)\nax.set_axisbelow(True)\n\n# Set axis limits with padding\nax.set_xlim(-1, len(df))\ny_min, y_max = df[\"low\"].min(), df[\"high\"].max()\ny_padding = (y_max - y_min) * 0.1\nax.set_ylim(y_min - y_padding, y_max + y_padding)\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}