{"spec_id":"hive-basic","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nhive-basic: Basic Hive Plot\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 94/100 | Updated: 2026-05-07\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom matplotlib.collections import LineCollection\n\n\n# Theme tokens\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\n# Okabe-Ito palette for axes (first 3 colors for 3 categories)\nAXIS_COLORS = [\"#009E73\", \"#C475FD\", \"#4467A3\"]\n\n# Create software module dependency network data\nnp.random.seed(42)\nnodes = [\n    # Core modules (axis 0)\n    {\"id\": \"core_engine\", \"axis\": 0, \"order\": 0.9, \"label\": \"Engine\"},\n    {\"id\": \"core_config\", \"axis\": 0, \"order\": 0.7, \"label\": \"Config\"},\n    {\"id\": \"core_logger\", \"axis\": 0, \"order\": 0.5, \"label\": \"Logger\"},\n    {\"id\": \"core_cache\", \"axis\": 0, \"order\": 0.3, \"label\": \"Cache\"},\n    # Utility modules (axis 1)\n    {\"id\": \"util_parser\", \"axis\": 1, \"order\": 0.85, \"label\": \"Parser\"},\n    {\"id\": \"util_validator\", \"axis\": 1, \"order\": 0.65, \"label\": \"Validator\"},\n    {\"id\": \"util_formatter\", \"axis\": 1, \"order\": 0.45, \"label\": \"Formatter\"},\n    {\"id\": \"util_converter\", \"axis\": 1, \"order\": 0.25, \"label\": \"Converter\"},\n    {\"id\": \"util_helper\", \"axis\": 1, \"order\": 0.15, \"label\": \"Helper\"},\n    # Interface modules (axis 2)\n    {\"id\": \"iface_api\", \"axis\": 2, \"order\": 0.95, \"label\": \"API\"},\n    {\"id\": \"iface_web\", \"axis\": 2, \"order\": 0.75, \"label\": \"Web\"},\n    {\"id\": \"iface_cli\", \"axis\": 2, \"order\": 0.55, \"label\": \"CLI\"},\n    {\"id\": \"iface_sdk\", \"axis\": 2, \"order\": 0.35, \"label\": \"SDK\"},\n]\n\nnode_lookup = {n[\"id\"]: n for n in nodes}\n\n# Dependencies between modules\nedges = [\n    (\"core_engine\", \"util_parser\"),\n    (\"core_engine\", \"util_validator\"),\n    (\"core_config\", \"util_parser\"),\n    (\"core_logger\", \"util_formatter\"),\n    (\"core_cache\", \"util_helper\"),\n    (\"util_parser\", \"iface_api\"),\n    (\"util_validator\", \"iface_api\"),\n    (\"util_formatter\", \"iface_web\"),\n    (\"util_converter\", \"iface_sdk\"),\n    (\"util_helper\", \"iface_cli\"),\n    (\"core_engine\", \"iface_api\"),\n    (\"core_config\", \"iface_cli\"),\n    (\"core_logger\", \"iface_web\"),\n    (\"core_engine\", \"core_config\"),\n    (\"core_engine\", \"core_logger\"),\n    (\"util_parser\", \"util_validator\"),\n    (\"iface_api\", \"iface_sdk\"),\n]\n\n# Hive plot configuration\nn_axes = 3\naxis_angles = [np.pi / 2 + i * 2 * np.pi / n_axes for i in range(n_axes)]\naxis_labels = [\"Core\", \"Utility\", \"Interface\"]\ninner_radius = 0.15\nouter_radius = 0.85\n\n# Plot\nfig, ax = plt.subplots(figsize=(12, 12), facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Draw axes as thick lines\nfor i in range(n_axes):\n    angle = axis_angles[i]\n    x_inner = inner_radius * np.cos(angle)\n    y_inner = inner_radius * np.sin(angle)\n    x_outer = outer_radius * np.cos(angle)\n    y_outer = outer_radius * np.sin(angle)\n\n    ax.plot([x_inner, x_outer], [y_inner, y_outer], color=AXIS_COLORS[i], linewidth=6, solid_capstyle=\"round\", zorder=1)\n\n    label_r = outer_radius + 0.08\n    label_x = label_r * np.cos(angle)\n    label_y = label_r * np.sin(angle)\n    ax.text(\n        label_x, label_y, axis_labels[i], fontsize=24, fontweight=\"bold\", ha=\"center\", va=\"center\", color=AXIS_COLORS[i]\n    )\n\n# Draw edges as curved bezier curves\nedge_lines = []\nedge_colors = []\n\nfor source_id, target_id in edges:\n    source = node_lookup[source_id]\n    target = node_lookup[target_id]\n\n    angle1 = axis_angles[source[\"axis\"]]\n    r1 = inner_radius + source[\"order\"] * (outer_radius - inner_radius)\n    x1 = r1 * np.cos(angle1)\n    y1 = r1 * np.sin(angle1)\n\n    angle2 = axis_angles[target[\"axis\"]]\n    r2 = inner_radius + target[\"order\"] * (outer_radius - inner_radius)\n    x2 = r2 * np.cos(angle2)\n    y2 = r2 * np.sin(angle2)\n\n    # Create bezier curve through center\n    t = np.linspace(0, 1, 50)\n    curve_x = (1 - t) ** 2 * x1 + 2 * (1 - t) * t * 0 + t**2 * x2\n    curve_y = (1 - t) ** 2 * y1 + 2 * (1 - t) * t * 0 + t**2 * y2\n\n    points = np.column_stack([curve_x, curve_y])\n    segments = np.array([points[:-1], points[1:]]).transpose(1, 0, 2)\n    edge_lines.extend(segments)\n    edge_colors.extend([AXIS_COLORS[source[\"axis\"]]] * len(segments))\n\nlc = LineCollection(edge_lines, colors=edge_colors, linewidths=2.5, alpha=0.4, zorder=2)\nax.add_collection(lc)\n\n# Draw nodes\nfor node in nodes:\n    angle = axis_angles[node[\"axis\"]]\n    r = inner_radius + node[\"order\"] * (outer_radius - inner_radius)\n    x = r * np.cos(angle)\n    y = r * np.sin(angle)\n    color = AXIS_COLORS[node[\"axis\"]]\n\n    ax.scatter(x, y, s=400, c=color, edgecolors=PAGE_BG, linewidths=2, zorder=3)\n\n    # Add node label with offset based on axis position\n    offset_dist = 0.08\n    if node[\"axis\"] == 0:\n        ha = \"left\"\n        label_x = x + offset_dist\n        label_y = y\n    elif node[\"axis\"] == 1:\n        ha = \"right\"\n        label_x = x - offset_dist * 0.5\n        label_y = y + offset_dist * 0.3\n    else:\n        ha = \"left\"\n        label_x = x + offset_dist * 0.5\n        label_y = y + offset_dist * 0.3\n\n    ax.text(label_x, label_y, node[\"label\"], fontsize=18, ha=ha, va=\"center\", color=INK)\n\n# Draw center point\nax.scatter(0, 0, s=200, c=PAGE_BG, edgecolors=INK_SOFT, linewidths=2, zorder=4)\n\n# Styling\nax.set_xlim(-1.1, 1.1)\nax.set_ylim(-1.1, 1.1)\nax.set_aspect(\"equal\")\nax.axis(\"off\")\n\n# Title\nax.set_title(\"hive-basic · matplotlib · anyplot.ai\", fontsize=28, fontweight=\"medium\", color=INK, pad=20)\n\n# Legend\nlegend_elements = [\n    plt.Line2D(\n        [0],\n        [0],\n        marker=\"o\",\n        color=\"w\",\n        markerfacecolor=AXIS_COLORS[i],\n        markersize=18,\n        markeredgecolor=PAGE_BG,\n        markeredgewidth=2,\n        label=axis_labels[i],\n    )\n    for i in range(n_axes)\n]\nleg = ax.legend(\n    handles=legend_elements, loc=\"lower center\", fontsize=18, frameon=True, ncol=3, bbox_to_anchor=(0.5, -0.05)\n)\nif leg:\n    leg.get_frame().set_facecolor(PAGE_BG)\n    leg.get_frame().set_edgecolor(INK_SOFT)\n    plt.setp(leg.get_texts(), color=INK_SOFT)\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}