{"spec_id":"polar-scatter","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\npolar-scatter: Polar Scatter Plot\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 92/100 | Updated: 2026-05-09\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\n\n\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\nIMPRINT = [\"#009E73\", \"#C475FD\"]\n\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,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n        \"grid.color\": INK,\n        \"grid.alpha\": 0.10,\n        \"legend.facecolor\": PAGE_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\n# Data - Wind measurements with prevailing directions\nnp.random.seed(42)\nn_points = 120\n\n# Morning winds: predominantly from SW (around 225 degrees)\nmorning_angles = np.random.normal(225, 30, n_points // 2) % 360\nmorning_speeds = np.random.gamma(3, 3, n_points // 2) + 5\n\n# Afternoon winds: predominantly from NE (around 45 degrees)\nafternoon_angles = np.random.normal(45, 40, n_points // 2) % 360\nafternoon_speeds = np.random.gamma(2.5, 4, n_points // 2) + 3\n\n# Combine data\nangles_deg = np.concatenate([morning_angles, afternoon_angles])\nspeeds = np.concatenate([morning_speeds, afternoon_speeds])\ntime_of_day = [\"Morning\"] * (n_points // 2) + [\"Afternoon\"] * (n_points // 2)\n\n# Convert to radians for plotting\nangles_rad = np.deg2rad(angles_deg)\n\n# Create DataFrame for seaborn\ndf = pd.DataFrame({\"angle_rad\": angles_rad, \"speed\": speeds, \"time_of_day\": time_of_day})\n\n# Create polar plot\nfig = plt.figure(figsize=(16, 9), facecolor=PAGE_BG)\nax = fig.add_subplot(111, projection=\"polar\")\n\n# Create scatter with Okabe-Ito colors\nsns.scatterplot(\n    data=df,\n    x=\"angle_rad\",\n    y=\"speed\",\n    hue=\"time_of_day\",\n    palette=IMPRINT,\n    hue_order=[\"Morning\", \"Afternoon\"],\n    s=150,\n    alpha=0.7,\n    ax=ax,\n    edgecolor=PAGE_BG,\n    linewidth=0.5,\n)\n\n# Configure polar plot appearance\nax.set_theta_zero_location(\"N\")\nax.set_theta_direction(-1)\n\n# Set angular ticks with cardinal directions\nax.set_xticks(np.deg2rad([0, 45, 90, 135, 180, 225, 270, 315]))\nax.set_xticklabels([\"N\", \"NE\", \"E\", \"SE\", \"S\", \"SW\", \"W\", \"NW\"], fontsize=18, color=INK_SOFT)\n\n# Configure radial axis\nmax_speed = max(speeds)\nax.set_ylim(0, max_speed * 1.1)\nax.tick_params(axis=\"y\", labelsize=16, colors=INK_SOFT)\n\n# Add radial label on the left side\nax.text(np.deg2rad(330), max_speed * 0.5, \"Wind Speed (m/s)\", fontsize=16, ha=\"center\", va=\"center\", color=INK)\n\n# Style the grid\nax.grid(True, alpha=0.15, linewidth=0.8)\n\n# Title\nax.set_title(\"polar-scatter · seaborn · anyplot.ai\", fontsize=24, fontweight=\"medium\", pad=20, color=INK)\n\n# Legend\nlegend = ax.legend(\n    title=\"Time of Day\",\n    title_fontsize=16,\n    fontsize=16,\n    loc=\"upper right\",\n    bbox_to_anchor=(1.1, 1.0),\n    framealpha=0.9,\n    facecolor=PAGE_BG,\n    edgecolor=INK_SOFT,\n)\nif legend.get_title():\n    legend.get_title().set_color(INK)\n    for t in legend.texts:\n        t.set_color(INK)\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}