{"spec_id":"polar-bar","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\npolar-bar: Polar Bar Chart (Wind Rose)\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 96/100 | Updated: 2026-05-13\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\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# Okabe-Ito palette (positions 1, 2, 3 for three series)\nBRAND = \"#009E73\"  # Position 1 (bluish green)\nACCENT1 = \"#C475FD\"  # Position 2 (vermillion)\nACCENT2 = \"#4467A3\"  # Position 3 (blue)\n\n# Data - Wind direction frequencies (8 compass directions)\nnp.random.seed(42)\ndirections = [\"N\", \"NE\", \"E\", \"SE\", \"S\", \"SW\", \"W\", \"NW\"]\nn_directions = len(directions)\n\n# Convert directions to angles (in radians, starting from N=0, clockwise)\nangles = np.linspace(0, 2 * np.pi, n_directions, endpoint=False)\n\n# Generate wind frequency data for 3 speed categories (stacked bars)\n# Calm (0-5 m/s), Moderate (5-10 m/s), Strong (>10 m/s)\ncalm = np.array([12, 8, 15, 6, 18, 10, 22, 14])\nmoderate = np.array([8, 5, 10, 4, 12, 7, 15, 9])\nstrong = np.array([4, 2, 5, 2, 6, 3, 8, 4])\n\n# Bar width (slightly less than full sector for visual separation)\nwidth = 2 * np.pi / n_directions * 0.8\n\n# Create polar plot (square format works well for radial charts)\nfig, ax = plt.subplots(figsize=(12, 12), subplot_kw={\"projection\": \"polar\"}, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Plot stacked bars with Okabe-Ito colors\nbars1 = ax.bar(\n    angles,\n    calm,\n    width=width,\n    bottom=0,\n    color=BRAND,\n    edgecolor=INK_SOFT,\n    linewidth=1.5,\n    label=\"Calm (0-5 m/s)\",\n    alpha=0.9,\n)\nbars2 = ax.bar(\n    angles,\n    moderate,\n    width=width,\n    bottom=calm,\n    color=ACCENT1,\n    edgecolor=INK_SOFT,\n    linewidth=1.5,\n    label=\"Moderate (5-10 m/s)\",\n    alpha=0.9,\n)\nbars3 = ax.bar(\n    angles,\n    strong,\n    width=width,\n    bottom=calm + moderate,\n    color=ACCENT2,\n    edgecolor=INK_SOFT,\n    linewidth=1.5,\n    label=\"Strong (>10 m/s)\",\n    alpha=0.9,\n)\n\n# Configure polar axes\nax.set_theta_zero_location(\"N\")  # North at top\nax.set_theta_direction(-1)  # Clockwise\n\n# Set direction labels\nax.set_xticks(angles)\nax.set_xticklabels(directions, fontsize=18, fontweight=\"bold\", color=INK)\n\n# Configure radial axis\nax.set_ylim(0, 50)\nax.set_yticks([10, 20, 30, 40])\nax.set_yticklabels([\"10%\", \"20%\", \"30%\", \"40%\"], fontsize=14, color=INK_SOFT)\nax.set_rlabel_position(45)  # Move radial labels to avoid overlap\n\n# Grid styling\nax.grid(True, alpha=0.15, linestyle=\"-\", linewidth=0.8, color=INK_SOFT)\n\n# Title\nax.set_title(\"polar-bar · matplotlib · anyplot.ai\", fontsize=24, pad=30, fontweight=\"bold\", color=INK)\n\n# Legend\nleg = ax.legend(loc=\"upper left\", bbox_to_anchor=(1.05, 1), fontsize=14, title=\"Wind Speed\", title_fontsize=16)\nif leg:\n    leg.get_frame().set_facecolor(ELEVATED_BG)\n    leg.get_frame().set_edgecolor(INK_SOFT)\n    leg.get_frame().set_linewidth(1)\n    plt.setp(leg.get_texts(), color=INK_SOFT)\n    plt.setp(leg.get_title(), color=INK)\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}