{"spec_id":"polar-line","library":"bokeh","language":"python","code":"\"\"\" anyplot.ai\npolar-line: Polar Line Plot\nLibrary: bokeh 3.9.0 | Python 3.13.13\nQuality: 80/100 | Updated: 2026-05-12\n\"\"\"\n\nimport numpy as np\nfrom bokeh.io import export_png\nfrom bokeh.models import ColumnDataSource\nfrom bokeh.plotting import figure, output_file, save\n\n\n# Data: Wind speed pattern over 24 hours (cyclical)\nnp.random.seed(42)\n\n# Hours of day (cyclical, 0-24)\nhours = np.linspace(0, 24, 25)\ntheta = hours * (2 * np.pi / 24)  # Convert to radians\n\n# Wind speed pattern: lower at night, higher during afternoon\nbase_pattern = 5 + 3 * np.sin(theta - np.pi / 2) + 2 * np.cos(2 * theta)\nwind_speed_day1 = base_pattern + np.random.normal(0, 0.5, len(theta))\nwind_speed_day2 = base_pattern * 0.8 + np.random.normal(0, 0.4, len(theta))\n\n# Ensure positive values\nwind_speed_day1 = np.maximum(wind_speed_day1, 0.5)\nwind_speed_day2 = np.maximum(wind_speed_day2, 0.5)\n\n# Close the loop by connecting last point to first\ntheta = np.append(theta, theta[0])\nwind_speed_day1 = np.append(wind_speed_day1, wind_speed_day1[0])\nwind_speed_day2 = np.append(wind_speed_day2, wind_speed_day2[0])\n\n# Convert polar to Cartesian for Bokeh (which doesn't have native polar support)\nx1 = wind_speed_day1 * np.cos(theta)\ny1 = wind_speed_day1 * np.sin(theta)\nx2 = wind_speed_day2 * np.cos(theta)\ny2 = wind_speed_day2 * np.sin(theta)\n\n# Create figure (square for polar plot)\np = figure(\n    width=3600,\n    height=3600,\n    title=\"polar-line · bokeh · pyplots.ai\",\n    x_axis_label=\"Wind Speed (m/s)\",\n    y_axis_label=\"Wind Speed (m/s)\",\n    x_range=(-12, 12),\n    y_range=(-12, 12),\n    tools=\"\",\n    toolbar_location=None,\n)\n\n# Draw concentric circles for radial grid\nfor r in [2, 4, 6, 8, 10]:\n    circle_theta = np.linspace(0, 2 * np.pi, 100)\n    cx = r * np.cos(circle_theta)\n    cy = r * np.sin(circle_theta)\n    p.line(cx, cy, line_color=\"#cccccc\", line_width=1.5, line_alpha=0.5)\n\n# Draw radial lines for angular grid (every 30 degrees = 2 hours)\nfor angle in np.linspace(0, 2 * np.pi, 12, endpoint=False):\n    p.line([0, 11 * np.cos(angle)], [0, 11 * np.sin(angle)], line_color=\"#cccccc\", line_width=1.5, line_alpha=0.5)\n\n# Add hour labels around the circle\nhour_labels = [\"0h\", \"2h\", \"4h\", \"6h\", \"8h\", \"10h\", \"12h\", \"14h\", \"16h\", \"18h\", \"20h\", \"22h\"]\nlabel_radius = 11.5\nfor i, label in enumerate(hour_labels):\n    angle = i * (2 * np.pi / 12)\n    lx = label_radius * np.cos(angle)\n    ly = label_radius * np.sin(angle)\n    p.text(\n        [lx],\n        [ly],\n        text=[label],\n        text_align=\"center\",\n        text_baseline=\"middle\",\n        text_font_size=\"18pt\",\n        text_color=\"#444444\",\n    )\n\n# Add radius labels\nfor r in [2, 4, 6, 8, 10]:\n    p.text([r + 0.3], [0.5], text=[f\"{r}\"], text_font_size=\"14pt\", text_color=\"#666666\")\n\n# Create data sources\nsource1 = ColumnDataSource(data={\"x\": x1, \"y\": y1})\nsource2 = ColumnDataSource(data={\"x\": x2, \"y\": y2})\n\n# Plot the polar lines\np.line(\"x\", \"y\", source=source1, line_color=\"#306998\", line_width=4, legend_label=\"Day 1\", line_alpha=0.9)\np.scatter(\"x\", \"y\", source=source1, color=\"#306998\", size=12, alpha=0.9)\n\np.line(\"x\", \"y\", source=source2, line_color=\"#FFD43B\", line_width=4, legend_label=\"Day 2\", line_alpha=0.9)\np.scatter(\"x\", \"y\", source=source2, color=\"#FFD43B\", size=12, alpha=0.9)\n\n# Style the plot\np.title.text_font_size = \"32pt\"\np.title.align = \"center\"\n\np.xaxis.axis_label_text_font_size = \"22pt\"\np.yaxis.axis_label_text_font_size = \"22pt\"\np.xaxis.major_label_text_font_size = \"18pt\"\np.yaxis.major_label_text_font_size = \"18pt\"\n\n# Hide the default axes for cleaner polar appearance\np.xaxis.visible = False\np.yaxis.visible = False\np.xgrid.visible = False\np.ygrid.visible = False\n\n# Style legend\np.legend.location = \"top_right\"\np.legend.label_text_font_size = \"18pt\"\np.legend.background_fill_alpha = 0.8\np.legend.border_line_color = \"#cccccc\"\np.legend.padding = 15\np.legend.spacing = 10\n\n# Background\np.background_fill_color = \"#fafafa\"\np.border_fill_color = \"#ffffff\"\np.outline_line_color = \"#dddddd\"\n\n# Save PNG and HTML\nexport_png(p, filename=\"plot.png\")\noutput_file(\"plot.html\", title=\"polar-line · bokeh · pyplots.ai\")\nsave(p)\n"}