{"spec_id":"streamline-basic","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nstreamline-basic: Basic Streamline Plot\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-05-14\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport plotly.graph_objects as go\nfrom scipy.integrate import solve_ivp\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\"\nGRID = \"rgba(26,26,23,0.10)\" if THEME == \"light\" else \"rgba(240,239,232,0.10)\"\nBRAND = \"#009E73\"\n\n# Data - Vortex flow field: u = -y, v = x (circular streamlines)\nfig = go.Figure()\n\n\n# Function to compute velocity at any point\ndef velocity_field(t, state):\n    x, y = state\n    dx = -y\n    dy = x\n    return [dx, dy]\n\n\n# Create streamlines from starting points on a circle\nnum_streamlines = 18\nfor angle in np.linspace(0, 2 * np.pi, num_streamlines, endpoint=False):\n    start_x = 2.5 * np.cos(angle)\n    start_y = 2.5 * np.sin(angle)\n\n    # Integrate forward\n    sol_forward = solve_ivp(\n        velocity_field, (0, 5), [start_x, start_y], t_eval=np.linspace(0, 5, 150), dense_output=True\n    )\n\n    # Integrate backward\n    sol_backward = solve_ivp(\n        velocity_field, (0, -5), [start_x, start_y], t_eval=np.linspace(0, -5, 150), dense_output=True\n    )\n\n    # Plot forward streamline\n    if sol_forward.t.size > 0:\n        fig.add_trace(\n            go.Scatter(\n                x=sol_forward.y[0],\n                y=sol_forward.y[1],\n                mode=\"lines\",\n                line={\"color\": BRAND, \"width\": 3},\n                hoverinfo=\"none\",\n                showlegend=False,\n            )\n        )\n\n    # Plot backward streamline\n    if sol_backward.t.size > 0:\n        fig.add_trace(\n            go.Scatter(\n                x=sol_backward.y[0],\n                y=sol_backward.y[1],\n                mode=\"lines\",\n                line={\"color\": BRAND, \"width\": 3},\n                hoverinfo=\"none\",\n                showlegend=False,\n            )\n        )\n\n# Update layout for large canvas with theme support\nfig.update_layout(\n    title={\"text\": \"streamline-basic · plotly · anyplot.ai\", \"font\": {\"size\": 28, \"color\": INK}, \"x\": 0.5, \"xanchor\": \"center\"},\n    xaxis={\n        \"title\": {\"text\": \"X Position (dimensionless)\", \"font\": {\"size\": 22, \"color\": INK}},\n        \"tickfont\": {\"size\": 18, \"color\": INK_SOFT},\n        \"showgrid\": True,\n        \"gridwidth\": 1,\n        \"gridcolor\": GRID,\n        \"zeroline\": True,\n        \"zerolinewidth\": 2,\n        \"zerolinecolor\": INK_SOFT,\n        \"range\": [-4, 4],\n        \"autorange\": False,\n        \"linecolor\": INK_SOFT,\n    },\n    yaxis={\n        \"title\": {\"text\": \"Y Position (dimensionless)\", \"font\": {\"size\": 22, \"color\": INK}},\n        \"tickfont\": {\"size\": 18, \"color\": INK_SOFT},\n        \"showgrid\": True,\n        \"gridwidth\": 1,\n        \"gridcolor\": GRID,\n        \"zeroline\": True,\n        \"zerolinewidth\": 2,\n        \"zerolinecolor\": INK_SOFT,\n        \"range\": [-4, 4],\n        \"autorange\": False,\n        \"scaleanchor\": \"x\",\n        \"scaleratio\": 1,\n        \"linecolor\": INK_SOFT,\n    },\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    font={\"color\": INK},\n    margin={\"l\": 120, \"r\": 50, \"t\": 100, \"b\": 100},\n    showlegend=False,\n)\n\n# Save as PNG and HTML\nfig.write_image(f\"plot-{THEME}.png\", width=1600, height=900, scale=3)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}