{"spec_id":"histogram-returns-distribution","library":"altair","language":"python","code":"\"\"\" anyplot.ai\nhistogram-returns-distribution: Returns Distribution Histogram\nLibrary: altair 6.1.0 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-05-20\n\"\"\"\n\nimport os\nimport sys\n\n\n# Prevent altair.py (this file) from shadowing the installed altair package:\n# Python puts the script's directory as sys.path[0], so we drop it.\n_script_dir = os.path.dirname(os.path.abspath(__file__))\nsys.path = [p for p in sys.path if p and os.path.abspath(p) != _script_dir]\n\nimport altair as alt\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nfrom scipy import stats\n\n\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\nBRAND = \"#009E73\"  # Okabe-Ito 1 — main distribution bars\nTAIL_COLOR = \"#C475FD\"  # Okabe-Ito 2 — tail bars beyond ±2σ\nCURVE_COLOR = \"#4467A3\"  # Okabe-Ito 3 — fitted normal distribution overlay\n\n# Data\nnp.random.seed(42)\nn_days = 252\nraw_returns = np.random.standard_t(df=5, size=n_days) * 0.015 + 0.0003\n# Clip at 1st–99th percentile to remove extreme outliers that compress the main distribution\nreturns = np.clip(raw_returns, np.percentile(raw_returns, 1), np.percentile(raw_returns, 99))\n\nmean_ret = np.mean(returns) * 100\nstd_ret = np.std(returns) * 100\nskewness = stats.skew(returns)\nkurtosis = stats.kurtosis(returns)\n\ndf_ret = pd.DataFrame({\"returns\": returns * 100})\n\nbin_count = 30\nhist_values, bin_edges = np.histogram(df_ret[\"returns\"], bins=bin_count, density=True)\nbin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2\n\nhist_df = pd.DataFrame(\n    {\"bin_center\": bin_centers, \"density\": hist_values, \"bin_start\": bin_edges[:-1], \"bin_end\": bin_edges[1:]}\n)\n\nlower_tail = mean_ret - 2 * std_ret\nupper_tail = mean_ret + 2 * std_ret\nhist_df[\"is_tail\"] = (hist_df[\"bin_center\"] < lower_tail) | (hist_df[\"bin_center\"] > upper_tail)\nhist_df[\"category\"] = np.where(hist_df[\"is_tail\"], \"Tail (±2σ)\", \"Returns\")\n\nx_range = np.linspace(df_ret[\"returns\"].min() - 0.5, df_ret[\"returns\"].max() + 0.5, 300)\nnormal_pdf = stats.norm.pdf(x_range, mean_ret, std_ret)\nnormal_df = pd.DataFrame({\"x\": x_range, \"density\": normal_pdf, \"category\": \"Normal dist.\"})\n\n# ±2σ reference lines\nsigma_df = pd.DataFrame({\"x\": [lower_tail, upper_tail]})\n\nstats_text = f\"Mean: {mean_ret:.2f}%\\nStd Dev: {std_ret:.2f}%\\nSkewness: {skewness:.2f}\\nKurtosis: {kurtosis:.2f}\"\nstats_df = pd.DataFrame({\"x\": [df_ret[\"returns\"].max() - 0.1], \"y\": [max(hist_values) * 0.95], \"text\": [stats_text]})\n\ntitle = \"histogram-returns-distribution · python · altair · anyplot.ai\"\n\n# Shared color scale — explicit domain shows all 3 entries in the legend even\n# though the histogram data only contains \"Returns\" and \"Tail (±2σ)\"\nCOLOR_DOMAIN = [\"Returns\", \"Tail (±2σ)\", \"Normal dist.\"]\nCOLOR_RANGE = [BRAND, TAIL_COLOR, CURVE_COLOR]\ncolor_scale = alt.Scale(domain=COLOR_DOMAIN, range=COLOR_RANGE)\n\n# Plot\nhistogram = (\n    alt.Chart(hist_df)\n    .mark_bar(opacity=0.8)\n    .encode(\n        x=alt.X(\"bin_start:Q\", bin=\"binned\", title=\"Returns (%)\"),\n        x2=\"bin_end:Q\",\n        y=alt.Y(\"density:Q\", title=\"Density\"),\n        color=alt.Color(\n            \"category:N\",\n            scale=color_scale,\n            legend=alt.Legend(title=None, orient=\"right\", labelFontSize=10, symbolSize=80),\n        ),\n        tooltip=[\n            alt.Tooltip(\"bin_center:Q\", title=\"Return (%)\", format=\".2f\"),\n            alt.Tooltip(\"density:Q\", title=\"Density\", format=\".4f\"),\n        ],\n    )\n)\n\nnormal_curve = (\n    alt.Chart(normal_df)\n    .mark_line(strokeWidth=3, strokeDash=[6, 3])\n    .encode(x=alt.X(\"x:Q\"), y=alt.Y(\"density:Q\"), color=alt.Color(\"category:N\", scale=color_scale, legend=None))\n)\n\n# Subtle ±2σ reference lines to mark tail cutoffs\nsigma_lines = (\n    alt.Chart(sigma_df)\n    .mark_rule(strokeDash=[4, 4], opacity=0.4, strokeWidth=1.5, color=INK_SOFT)\n    .encode(x=alt.X(\"x:Q\"))\n)\n\nstats_annotation = (\n    alt.Chart(stats_df)\n    .mark_text(align=\"right\", baseline=\"top\", fontSize=13, color=INK_SOFT, lineBreak=\"\\n\")\n    .encode(x=alt.X(\"x:Q\"), y=alt.Y(\"y:Q\"), text=\"text:N\")\n)\n\nchart = (\n    alt.layer(histogram, sigma_lines, normal_curve, stats_annotation)\n    .properties(\n        width=560,\n        height=320,\n        background=PAGE_BG,\n        padding={\"left\": 0, \"right\": 0, \"top\": 0, \"bottom\": 0},\n        title=alt.Title(title, fontSize=16, anchor=\"middle\"),\n    )\n    .configure_view(fill=PAGE_BG, strokeWidth=0, continuousWidth=560, continuousHeight=320)\n    .configure_axis(\n        labelFontSize=10,\n        titleFontSize=12,\n        domainColor=INK_SOFT,\n        tickColor=INK_SOFT,\n        gridColor=INK,\n        gridOpacity=0.10,\n        labelColor=INK_SOFT,\n        titleColor=INK,\n    )\n    .configure_title(color=INK)\n    .configure_legend(\n        fillColor=ELEVATED_BG,\n        strokeColor=INK_SOFT,\n        labelColor=INK_SOFT,\n        titleColor=INK,\n        labelFontSize=10,\n        titleFontSize=10,\n    )\n)\n\n# Save\nchart.save(f\"plot-{THEME}.png\", scale_factor=4.0)\n\nTW, TH = 3200, 1800\n_img = Image.open(f\"plot-{THEME}.png\").convert(\"RGB\")\n_w, _h = _img.size\nif _w > TW or _h > TH:\n    raise SystemExit(\n        f\"altair vl-convert produced {_w}×{_h}, exceeds target {TW}×{TH}. \"\n        f\"Shrink chart .properties(width=, height=) values and re-render.\"\n    )\nif _w < TW or _h < TH:\n    _bg_rgb = (250, 248, 241) if THEME == \"light\" else (26, 26, 23)\n    _canvas = Image.new(\"RGB\", (TW, TH), _bg_rgb)\n    _canvas.paste(_img, ((TW - _w) // 2, (TH - _h) // 2))\n    _canvas.save(f\"plot-{THEME}.png\")\n\nchart.save(f\"plot-{THEME}.html\")\n"}