{"spec_id":"area-elevation-profile","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\narea-elevation-profile: Terrain Elevation Profile Along Transect\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-06-10\n\"\"\"\n\nimport os\nimport sys\n\n\n# Prevent this file from shadowing the installed matplotlib package on sys.path\n_this_dir = os.path.dirname(os.path.abspath(__file__))\nif _this_dir in sys.path:\n    sys.path.remove(_this_dir)\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom matplotlib.colors import LinearSegmentedColormap\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# Data — Alpine hiking trail profile (120 km)\nnp.random.seed(42)\nnum_points = 480\ndistance = np.linspace(0, 120, num_points)\n\n# Build realistic terrain with multiple peaks and valleys\nbase = 1200\nelevation = base + np.zeros(num_points)\nelevation += 600 * np.exp(-((distance - 25) ** 2) / 80)\nelevation += 900 * np.exp(-((distance - 55) ** 2) / 120)\nelevation += 450 * np.exp(-((distance - 85) ** 2) / 60)\nelevation += 700 * np.exp(-((distance - 105) ** 2) / 90)\nelevation += 200 * np.sin(distance * 0.15) * np.exp(-((distance - 40) ** 2) / 300)\nelevation += 150 * np.cos(distance * 0.25)\nelevation += np.cumsum(np.random.normal(0, 1.5, num_points))\nelevation = np.maximum(elevation, 800)\n\n# Landmarks\nlandmark_labels = [\"Bergdorf\", \"Sonnalm\", \"Hoher Kamm\", \"Talbach\", \"Gipfelkreuz\", \"Seefeld Hut\", \"Felsgrat\", \"Alpstadt\"]\nlandmark_distances = [0, 18, 28, 42, 55, 72, 88, 120]\nlandmark_elevations = [\n    elevation[0],\n    elevation[np.argmin(np.abs(distance - 18))],\n    elevation[np.argmin(np.abs(distance - 28))],\n    elevation[np.argmin(np.abs(distance - 42))],\n    elevation[np.argmin(np.abs(distance - 55))],\n    elevation[np.argmin(np.abs(distance - 72))],\n    elevation[np.argmin(np.abs(distance - 88))],\n    elevation[-1],\n]\nlandmark_names = [\n    f\"{name}\\n{int(round(elev))} m\" for name, elev in zip(landmark_labels, landmark_elevations, strict=True)\n]\n\n# Plot\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\ny_min = 600\ny_max = elevation.max()\n\n# Gradient fill — terrain silhouette (imprint_seq: brand green → blue)\ncmap = LinearSegmentedColormap.from_list(\"imprint_seq\", [\"#009E73\", \"#4467A3\"])\ngradient_resolution = 200\ny_levels = np.linspace(y_min, y_max, gradient_resolution)\nfor i in range(len(y_levels) - 1):\n    y_lo = y_levels[i]\n    y_hi = y_levels[i + 1]\n    clipped = np.clip(elevation, y_lo, y_hi)\n    color = cmap(i / (len(y_levels) - 1))\n    ax.fill_between(distance, y_lo, clipped, color=color, alpha=0.9, linewidth=0)\n\n# Profile line — brand green primary data element\nax.plot(distance, elevation, color=\"#009E73\", linewidth=2.0, zorder=3)\n\n# Landmark annotations — stagger to separate the 18–28 km cluster\n# Sonnalm pushed up high (horiz-centered) so it clears Hoher Kamm without going left into Bergdorf\nlabel_configs = [\n    (\"left\", (6, 12)),  # Bergdorf    (0 km)  — text right\n    (\"center\", (0, 42)),  # Sonnalm     (18 km) — pushed up, clears Hoher Kamm below\n    (\"left\", (6, 12)),  # Hoher Kamm  (28 km) — text right, at normal height\n    (\"center\", (0, 12)),  # Talbach     (42 km)\n    (\"center\", (0, 28)),  # Gipfelkreuz (55 km) — pushed up as focal peak\n    (\"center\", (0, 12)),  # Seefeld Hut (72 km)\n    (\"center\", (0, 12)),  # Felsgrat    (88 km)\n    (\"right\", (-6, 12)),  # Alpstadt    (120 km) — text left\n]\nfor (ha, (dx, dy)), name, d, e in zip(\n    label_configs, landmark_names, landmark_distances, landmark_elevations, strict=True\n):\n    ax.plot([d, d], [y_min, e], color=INK_SOFT, linewidth=0.8, linestyle=\"--\", alpha=0.4, zorder=2)\n    ax.plot(d, e, \"o\", color=INK, markersize=5, zorder=4, markeredgecolor=PAGE_BG, markeredgewidth=1)\n    ax.annotate(\n        name,\n        xy=(d, e),\n        xytext=(dx, dy),\n        textcoords=\"offset points\",\n        fontsize=9,\n        fontweight=\"bold\",\n        ha=ha,\n        va=\"bottom\",\n        color=INK,\n    )\n\n# Style\ntitle = \"Alpine Trail Profile · area-elevation-profile · python · matplotlib · anyplot.ai\"\ntitle_len = len(title)\ntitle_fontsize = max(8, round(12 * 67 / title_len)) if title_len > 67 else 12\nax.set_xlabel(\"Distance (km)\", fontsize=10, color=INK)\nax.set_ylabel(\"Elevation (m)\", fontsize=10, color=INK)\nax.set_title(title, fontsize=title_fontsize, fontweight=\"medium\", color=INK)\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)\nax.set_xlim(0, 120)\nax.set_ylim(y_min, y_max + 350)\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)\n\n# Vertical exaggeration note\nax.text(\n    0.99,\n    0.02,\n    \"Vertical exaggeration ≈ 10×\",\n    transform=ax.transAxes,\n    fontsize=8,\n    ha=\"right\",\n    va=\"bottom\",\n    color=INK_MUTED,\n    fontstyle=\"italic\",\n    bbox={\"boxstyle\": \"round,pad=0.3\", \"facecolor\": ELEVATED_BG, \"edgecolor\": INK_SOFT, \"alpha\": 0.85},\n)\n\nfig.subplots_adjust(left=0.09, right=0.98, top=0.91, bottom=0.12)\n\n# Save\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}