{"spec_id":"sparkline-basic","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nsparkline-basic: Basic Sparkline\nLibrary: plotly 6.8.0 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-06-16\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport plotly.graph_objects as go\n\n\n# Theme tokens (see prompts/default-style-guide.md \"Theme-adaptive Chrome\")\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\n# Imprint palette\nBRAND = \"#009E73\"  # position 1 — the single data series (always first)\nPEAK = \"#4467A3\"  # position 3 — high / max marker\nTROUGH = \"#AE3030\"  # position 5 — semantic red for low / min marker\nAREA_FILL = \"rgba(0,158,115,0.12)\"  # brand green, soft area under the line\n\n# Data — inline daily stock closing prices (a classic sparkline use case)\nnp.random.seed(42)\nn_days = 60\ndaily_returns = np.random.randn(n_days) * 0.018\nprices = 180 * np.cumprod(1 + daily_returns)\ndays = np.arange(n_days)\n\nmin_idx = int(np.argmin(prices))\nmax_idx = int(np.argmax(prices))\n\n# Plot — a single clean sparkline compressed into a wide, short band\nfig = go.Figure()\n\n# Soft filled area beneath the line for the trend's shape\nfig.add_trace(\n    go.Scatter(\n        x=days,\n        y=prices,\n        mode=\"lines\",\n        line={\"color\": BRAND, \"width\": 4, \"shape\": \"spline\", \"smoothing\": 0.6},\n        fill=\"tozeroy\",\n        fillcolor=AREA_FILL,\n        hovertemplate=\"Day %{x}<br>$%{y:.2f}<extra></extra>\",\n        name=\"Close\",\n    )\n)\n\n# Min point (trough) — semantic red\nfig.add_trace(\n    go.Scatter(\n        x=[days[min_idx]],\n        y=[prices[min_idx]],\n        mode=\"markers\",\n        marker={\"color\": TROUGH, \"size\": 20, \"line\": {\"color\": PAGE_BG, \"width\": 3}},\n        hovertemplate=\"Low $%{y:.2f}<extra></extra>\",\n        name=\"Low\",\n    )\n)\n\n# Max point (peak) — Imprint blue\nfig.add_trace(\n    go.Scatter(\n        x=[days[max_idx]],\n        y=[prices[max_idx]],\n        mode=\"markers\",\n        marker={\"color\": PEAK, \"size\": 20, \"line\": {\"color\": PAGE_BG, \"width\": 3}},\n        hovertemplate=\"High $%{y:.2f}<extra></extra>\",\n        name=\"High\",\n    )\n)\n\n# Current (last) value — emphasized endpoint in brand green with a value label\nfig.add_trace(\n    go.Scatter(\n        x=[days[-1]],\n        y=[prices[-1]],\n        mode=\"markers+text\",\n        marker={\"color\": BRAND, \"size\": 22, \"line\": {\"color\": PAGE_BG, \"width\": 3}},\n        text=[f\"${prices[-1]:.0f}\"],\n        textposition=\"top center\",\n        textfont={\"color\": BRAND, \"size\": 18},\n        hovertemplate=\"Current $%{y:.2f}<extra></extra>\",\n        name=\"Current\",\n    )\n)\n\n# Style — pure sparkline: no axes, gridlines, ticks, or legend\npad = (prices.max() - prices.min()) * 0.25\nfig.update_layout(\n    autosize=False,\n    title={\n        \"text\": \"sparkline-basic · python · plotly · anyplot.ai\",\n        \"font\": {\"size\": 20, \"color\": INK},\n        \"x\": 0.5,\n        \"xanchor\": \"center\",\n        \"y\": 0.9,\n    },\n    xaxis={\"visible\": False, \"showgrid\": False, \"zeroline\": False, \"showticklabels\": False},\n    yaxis={\n        \"visible\": False,\n        \"showgrid\": False,\n        \"zeroline\": False,\n        \"showticklabels\": False,\n        \"range\": [prices.min() - pad, prices.max() + pad],\n        \"domain\": [0.36, 0.72],  # compress the line into a wide, short sparkline band\n    },\n    showlegend=False,\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    font={\"color\": INK_SOFT},\n    margin={\"l\": 70, \"r\": 70, \"t\": 120, \"b\": 70},\n)\n\n# Save — hard target 3200 × 1800 (landscape)\nfig.write_image(f\"plot-{THEME}.png\", width=800, height=450, scale=4)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}