{"spec_id":"gauge-basic","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\ngauge-basic: Basic Gauge Chart\nLibrary: seaborn 0.13.2 | Python 3.13.14\nQuality: 89/100 | Updated: 2026-06-30\n\"\"\"\n\nimport os\nimport sys\n\n\n# matplotlib.py in this directory is a sibling implementation — remove own dir from sys.path\n# so it does not shadow the installed matplotlib package\n_own_dir = os.path.dirname(os.path.abspath(__file__))\nsys.path = [p for p in sys.path if not p or os.path.abspath(p) != _own_dir]\n\nimport matplotlib.patheffects as pe\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nfrom matplotlib.patches import Circle, Wedge\n\n\n# Imprint palette chrome — theme-adaptive\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 semantic anchors for CPU health zones (low usage = good, high = danger)\nZONE_NORMAL = \"#009E73\"  # Imprint green — healthy CPU load\nZONE_MODERATE = \"#DDCC77\"  # Imprint amber — elevated load, caution\nZONE_HIGH = \"#AE3030\"  # Imprint red — high CPU, intervention needed\n\n# Data — production server CPU utilization\nvalue = 83\nmin_value = 0\nmax_value = 100\nthresholds = [40, 80]  # 0–40: Normal, 40–80: Moderate, 80–100: High\n\n# Historical readings for seaborn sparkline (minutes_ago=0 is current reading)\nhistory_minutes = list(range(10, -1, -1))\nhistory_cpu = [72, 68, 74, 79, 77, 82, 85, 81, 84, 86, 83]\nspark_df = pd.DataFrame({\"minutes_ago\": history_minutes, \"cpu\": history_cpu})\n\n# Gauge geometry (unit-square axis coordinates)\ncenter = (0.5, 0.48)\nradius = 0.34  # reduced from 0.38 for better breathing room\nwidth = 0.14\nstart_angle = 180\nend_angle = 0\nangle_range = start_angle - end_angle\nvalue_range = max_value - min_value\n\nzone_boundaries = [min_value] + thresholds + [max_value]\nzone_names = [\"Normal\", \"Moderate\", \"High\"]\nzone_colors = [ZONE_NORMAL, ZONE_MODERATE, ZONE_HIGH]\n\n# Seaborn theme with Imprint chrome — applies globally to all axes\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_MUTED,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n        \"grid.color\": INK,\n        \"grid.alpha\": 0.15,\n        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\nfig, ax = plt.subplots(figsize=(6, 6), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Arc zones — Wedge patches for each CPU health band\nfor i in range(len(zone_boundaries) - 1):\n    z_start = start_angle - (zone_boundaries[i] - min_value) / value_range * angle_range\n    z_end = start_angle - (zone_boundaries[i + 1] - min_value) / value_range * angle_range\n    ax.add_patch(\n        Wedge(\n            center=center,\n            r=radius + width / 2,\n            theta1=z_end,\n            theta2=z_start,\n            width=width,\n            facecolor=zone_colors[i],\n            edgecolor=\"none\",\n            linewidth=0,\n            zorder=2,\n        )\n    )\n\n# Zone boundary dividers — thin radial cuts in INK_SOFT\nfor threshold in thresholds:\n    angle = start_angle - (threshold - min_value) / value_range * angle_range\n    rad = np.radians(angle)\n    rs = (radius - width / 2, radius + width / 2)\n    ax.plot(\n        [center[0] + r * np.cos(rad) for r in rs],\n        [center[1] + r * np.sin(rad) for r in rs],\n        color=INK_SOFT,\n        linewidth=2,\n        zorder=3,\n        solid_capstyle=\"butt\",\n    )\n\n# Needle — points to current CPU utilization\nneedle_angle = start_angle - (value - min_value) / value_range * angle_range\nneedle_rad = np.radians(needle_angle)\nneedle_length = radius + width / 2 - 0.012\nneedle_tip_x = center[0] + needle_length * np.cos(needle_rad)\nneedle_tip_y = center[1] + needle_length * np.sin(needle_rad)\nax.plot([center[0], needle_tip_x], [center[1], needle_tip_y], color=INK, linewidth=3, zorder=12, solid_capstyle=\"round\")\n\n# Hub — page-bg ring + ink disc for crisp look in both themes\nax.add_patch(Circle(center, radius=0.045, facecolor=PAGE_BG, edgecolor=\"none\", zorder=13))\nax.add_patch(Circle(center, radius=0.035, facecolor=INK, edgecolor=\"none\", zorder=14))\n\n# Value display — bold reading centered below gauge\nax.text(center[0], center[1] - 0.17, f\"{value}%\", ha=\"center\", va=\"center\", fontsize=32, fontweight=\"bold\", color=INK)\n\n# Context label — fontsize=11 for mobile legibility\nax.text(center[0], center[1] - 0.26, \"CPU Utilization\", ha=\"center\", va=\"center\", fontsize=11, color=INK_MUTED)\n\n# Min / max scale endpoints\nfor vlabel, x_off in [(min_value, -1), (max_value, 1)]:\n    ax.text(\n        center[0] + x_off * radius, center[1] - 0.055, f\"{vlabel}\", ha=\"center\", va=\"top\", fontsize=10, color=INK_SOFT\n    )\n\n# Zone labels on arc — white text with PAGE_BG stroke (theme-adaptive halo)\nzone_label_centers = [\n    (thresholds[0] - min_value) / 2 + min_value,\n    (thresholds[0] + thresholds[1]) / 2,\n    (thresholds[1] + max_value) / 2,\n]\nfor v_center, label in zip(zone_label_centers, zone_names, strict=True):\n    angle = start_angle - (v_center - min_value) / value_range * angle_range\n    rad = np.radians(angle)\n    lx = center[0] + radius * np.cos(rad)\n    ly = center[1] + radius * np.sin(rad)\n    txt = ax.text(lx, ly, label, ha=\"center\", va=\"center\", fontsize=11, color=\"white\", fontweight=\"bold\", zorder=5)\n    txt.set_path_effects([pe.withStroke(linewidth=2, foreground=PAGE_BG)])\n\n# Title\nax.set_title(\"gauge-basic · python · seaborn · anyplot.ai\", fontsize=12, fontweight=\"medium\", pad=16, color=INK)\n\n# Canvas — pure coordinate space, no axes chrome\nax.set_xlim(0, 1)\nax.set_ylim(0, 1)\nax.set_aspect(\"equal\")\nax.axis(\"off\")\n\n# Reserve bottom 22% of figure for seaborn sparkline, then adjust\nplt.tight_layout()\nplt.subplots_adjust(bottom=0.22)\n\n# Seaborn lineplot sparkline — 10-minute CPU history (genuine sns.lineplot usage)\nax_spark = fig.add_axes([0.12, 0.04, 0.76, 0.14], facecolor=PAGE_BG)\nsns.lineplot(data=spark_df, x=\"minutes_ago\", y=\"cpu\", ax=ax_spark, color=INK_SOFT, linewidth=1.5)\n# Highlight current reading with a red dot\nax_spark.scatter([0], [value], color=ZONE_HIGH, s=22, zorder=5)\n# Zone threshold reference lines\nax_spark.axhline(80, color=ZONE_HIGH, alpha=0.25, linewidth=0.7, linestyle=\"--\")\nax_spark.axhline(40, color=ZONE_MODERATE, alpha=0.25, linewidth=0.7, linestyle=\"--\")\n# Reversed x-axis: oldest (10 min ago) on left, newest (\"now\") on right\nax_spark.set_xlim(10.5, -0.5)\nax_spark.set_ylim(0, 100)\nax_spark.set_xticks([10, 5, 0])\nax_spark.set_xticklabels([\"10m\", \"5m\", \"now\"], fontsize=6, color=INK_SOFT)\nax_spark.set_yticks([40, 80])\nax_spark.set_yticklabels([\"40%\", \"80%\"], fontsize=6, color=INK_SOFT)\nax_spark.tick_params(axis=\"both\", length=2, pad=1, colors=INK_SOFT)\nax_spark.set_xlabel(\"\")\nax_spark.set_facecolor(PAGE_BG)\nax_spark.yaxis.grid(True, alpha=0.12, linewidth=0.5, color=INK)\nfor spine in ax_spark.spines.values():\n    spine.set_edgecolor(INK_SOFT)\n    spine.set_linewidth(0.4)\n    spine.set_alpha(0.4)\n\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}