{"spec_id":"polar-line","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\npolar-line: Polar Line Plot\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 75/100 | Updated: 2026-05-12\n\"\"\"\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import (\n    LetsPlot,\n    aes,\n    coord_fixed,\n    element_text,\n    geom_path,\n    geom_point,\n    geom_text,\n    ggplot,\n    ggsize,\n    labs,\n    scale_color_manual,\n    theme,\n    theme_void,\n)\nfrom lets_plot.export import ggsave\n\n\nLetsPlot.setup_html()\n\n# Data - Monthly average temperature pattern (cyclical)\nnp.random.seed(42)\nmonths = np.arange(0, 360, 30)  # 12 months as angles (0, 30, 60, ... 330)\nmonth_names = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n\n# Simulated temperature pattern (warm summer, cold winter)\ntemp_city_a = np.array([2, 4, 10, 15, 20, 25, 28, 27, 22, 14, 7, 3])\ntemp_city_b = np.array([5, 7, 12, 17, 22, 27, 30, 29, 24, 16, 10, 6])\n\n# Close the loop by adding the first point at the end\nangles_closed = np.append(months, 360)\ntemp_a_closed = np.append(temp_city_a, temp_city_a[0])\ntemp_b_closed = np.append(temp_city_b, temp_city_b[0])\n\n# Convert to radians for polar coordinates\ntheta_a = np.radians(angles_closed)\ntheta_b = np.radians(angles_closed)\n\n# Create x, y coordinates from polar (for lets-plot which uses Cartesian)\nx_a = temp_a_closed * np.cos(theta_a)\ny_a = temp_a_closed * np.sin(theta_a)\nx_b = temp_b_closed * np.cos(theta_b)\ny_b = temp_b_closed * np.sin(theta_b)\n\n# Create DataFrame\ndf = pd.DataFrame(\n    {\n        \"x\": np.concatenate([x_a, x_b]),\n        \"y\": np.concatenate([y_a, y_b]),\n        \"radius\": np.concatenate([temp_a_closed, temp_b_closed]),\n        \"angle\": np.concatenate([angles_closed, angles_closed]),\n        \"city\": [\"City A\"] * len(x_a) + [\"City B\"] * len(x_b),\n    }\n)\n\n# Create concentric circles for polar grid\ngrid_radii = [10, 20, 30]\ncircle_points = 100\ngrid_circles = []\nfor r in grid_radii:\n    theta_grid = np.linspace(0, 2 * np.pi, circle_points)\n    grid_circles.append(pd.DataFrame({\"x\": r * np.cos(theta_grid), \"y\": r * np.sin(theta_grid), \"radius\": r}))\ngrid_df = pd.concat(grid_circles, ignore_index=True)\n\n# Create radial lines for grid (every 30 degrees = each month)\nradial_lines = []\nfor angle_deg in range(0, 360, 30):\n    angle_rad = np.radians(angle_deg)\n    radial_lines.append(\n        pd.DataFrame({\"x\": [0, 35 * np.cos(angle_rad)], \"y\": [0, 35 * np.sin(angle_rad)], \"angle\": angle_deg})\n    )\nradial_df = pd.concat(radial_lines, ignore_index=True)\n\n# Month labels positions\nlabel_radius = 34\nmonth_labels_df = pd.DataFrame(\n    {\n        \"x\": [label_radius * np.cos(np.radians(a)) for a in months],\n        \"y\": [label_radius * np.sin(np.radians(a)) for a in months],\n        \"label\": month_names,\n    }\n)\n\n# Plot\nplot = (\n    ggplot()\n    # Concentric grid circles\n    + geom_path(aes(x=\"x\", y=\"y\", group=\"radius\"), data=grid_df, color=\"#CCCCCC\", size=0.5, alpha=0.6)\n    # Radial grid lines\n    + geom_path(aes(x=\"x\", y=\"y\", group=\"angle\"), data=radial_df, color=\"#CCCCCC\", size=0.5, alpha=0.6)\n    # Data lines\n    + geom_path(aes(x=\"x\", y=\"y\", color=\"city\"), data=df, size=2)\n    # Data points\n    + geom_point(aes(x=\"x\", y=\"y\", color=\"city\"), data=df, size=5)\n    # Month labels\n    + geom_text(aes(x=\"x\", y=\"y\", label=\"label\"), data=month_labels_df, size=14, color=\"#333333\")\n    # Colors\n    + scale_color_manual(values=[\"#306998\", \"#FFD43B\"])\n    # Theme and labels\n    + labs(title=\"polar-line · letsplot · pyplots.ai\", color=\"Location\")\n    + theme_void()\n    + theme(\n        plot_title=element_text(size=24, hjust=0.5),\n        legend_position=\"right\",\n        legend_title=element_text(size=18),\n        legend_text=element_text(size=16),\n    )\n    + coord_fixed()\n    + ggsize(1600, 900)\n)\n\n# Save\nggsave(plot, \"plot.png\", path=\".\", scale=3)\n\n# Also save HTML for interactive version\nggsave(plot, \"plot.html\", path=\".\")\n"}