{"spec_id":"scatter-connected-temporal","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nscatter-connected-temporal: Connected Scatter Plot with Temporal Path\nLibrary: plotly 6.8.0 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-06-09\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport plotly.colors as pc\nimport plotly.graph_objects as go\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\nGRID = \"rgba(26,26,23,0.15)\" if THEME == \"light\" else \"rgba(240,239,232,0.15)\"\n\n# Imprint sequential colormap — green (#009E73) → blue (#4467A3)\nimprint_seq = [[0.0, \"#009E73\"], [1.0, \"#4467A3\"]]\n\n# Data - US Phillips Curve: Unemployment vs Inflation (1990-2023)\nyears = np.arange(1990, 2024)\nn = len(years)\n\nunemployment = np.array(\n    [\n        5.6,\n        6.8,\n        7.5,\n        6.9,\n        6.1,\n        5.6,\n        5.4,\n        4.9,\n        4.5,\n        4.2,  # 1990s recovery\n        4.0,\n        4.7,\n        5.8,\n        6.0,\n        5.5,\n        5.1,\n        4.6,\n        4.6,\n        5.8,\n        9.3,  # 2000s + recession\n        9.6,\n        8.9,\n        8.1,\n        7.4,\n        6.2,\n        5.3,\n        4.9,\n        4.4,\n        3.9,\n        3.7,  # 2010s recovery\n        8.1,\n        5.4,\n        3.6,\n        3.6,  # 2020s pandemic\n    ]\n)\n\ninflation = np.array(\n    [\n        5.4,\n        4.2,\n        3.0,\n        3.0,\n        2.6,\n        2.8,\n        3.0,\n        2.3,\n        1.6,\n        2.2,  # 1990s\n        3.4,\n        2.8,\n        1.6,\n        2.3,\n        2.7,\n        3.4,\n        3.2,\n        2.8,\n        3.8,\n        -0.4,  # 2000s\n        1.6,\n        3.2,\n        2.1,\n        1.5,\n        1.6,\n        0.1,\n        1.3,\n        2.1,\n        2.4,\n        1.8,  # 2010s\n        1.2,\n        4.7,\n        8.0,\n        4.1,  # 2020s\n    ]\n)\n\nt_norm = np.linspace(0, 1, n)\n\nfig = go.Figure()\n\n# Line segments colored by Imprint sequential gradient\nseg_colors = pc.sample_colorscale(imprint_seq, [t_norm[i] for i in range(n - 1)])\n\nfor i in range(n - 1):\n    r, g, b = pc.unlabel_rgb(seg_colors[i])\n    fig.add_trace(\n        go.Scatter(\n            x=unemployment[i : i + 2],\n            y=inflation[i : i + 2],\n            mode=\"lines\",\n            line={\"color\": f\"rgba({r}, {g}, {b}, 0.6)\", \"width\": 3.5},\n            hoverinfo=\"skip\",\n            showlegend=False,\n        )\n    )\n\n# Data points with Imprint sequential gradient and colorbar\nfig.add_trace(\n    go.Scatter(\n        x=unemployment,\n        y=inflation,\n        mode=\"markers\",\n        marker={\n            \"size\": 14,\n            \"color\": t_norm,\n            \"colorscale\": imprint_seq,\n            \"line\": {\"color\": PAGE_BG, \"width\": 2},\n            \"colorbar\": {\n                \"title\": {\"text\": \"Year\", \"font\": {\"size\": 12, \"color\": INK}},\n                \"tickvals\": [0, 0.2, 0.4, 0.6, 0.8, 1],\n                \"ticktext\": [\"1990\", \"1997\", \"2003\", \"2010\", \"2017\", \"2023\"],\n                \"tickfont\": {\"size\": 10, \"color\": INK_SOFT},\n                \"len\": 0.75,\n                \"thickness\": 18,\n                \"outlinewidth\": 0,\n                \"x\": 1.02,\n                \"bgcolor\": PAGE_BG,\n            },\n        },\n        customdata=np.column_stack([years, unemployment, inflation]),\n        hovertemplate=(\n            \"<b>%{customdata[0]:.0f}</b><br>\"\n            \"Unemployment: %{customdata[1]:.1f}%<br>\"\n            \"Inflation: %{customdata[2]:.1f}%\"\n            \"<extra></extra>\"\n        ),\n        showlegend=False,\n    )\n)\n\n# Year annotations at key time points\nkey_points = {\n    0: (\"1990\", 45, -35),\n    9: (\"1999\", -50, -40),\n    19: (\"2009\", 50, 30),\n    30: (\"2020\", -55, 35),\n    32: (\"2022\", -55, -35),\n    33: (\"2023\", 50, -30),\n}\n\nfor idx, (label, ax_off, ay_off) in key_points.items():\n    fig.add_annotation(\n        x=unemployment[idx],\n        y=inflation[idx],\n        text=f\"<b>{label}</b>\",\n        showarrow=True,\n        arrowhead=0,\n        arrowcolor=INK_MUTED,\n        arrowwidth=1.5,\n        ax=ax_off,\n        ay=ay_off,\n        font={\"size\": 11, \"color\": INK},\n        bgcolor=ELEVATED_BG,\n        borderpad=4,\n    )\n\n# Directional arrows indicating temporal flow\nfor start_idx, end_idx in [(10, 13), (27, 30)]:\n    fig.add_annotation(\n        x=unemployment[end_idx],\n        y=inflation[end_idx],\n        ax=unemployment[start_idx],\n        ay=inflation[start_idx],\n        xref=\"x\",\n        yref=\"y\",\n        axref=\"x\",\n        ayref=\"y\",\n        showarrow=True,\n        arrowhead=3,\n        arrowsize=2,\n        arrowwidth=2.5,\n        arrowcolor=INK_SOFT,\n        opacity=0.6,\n    )\n\n# Decade labels for context\nfor x_pos, y_pos, decade in [(6.8, 5.0, \"1990s\"), (7.8, -0.1, \"2000s\"), (4.0, 0.3, \"2010s\"), (5.8, 7.5, \"2020s\")]:\n    fig.add_annotation(\n        x=x_pos, y=y_pos, text=f\"<i>{decade}</i>\", showarrow=False, font={\"size\": 12, \"color\": INK_MUTED}\n    )\n\n# Layout\ntitle_text = \"scatter-connected-temporal · python · plotly · anyplot.ai\"\ntitle_n = len(title_text)\ntitle_size = max(round(16 * (67 / title_n if title_n > 67 else 1.0)), 11)\n\nfig.update_layout(\n    autosize=False,\n    title={\"text\": title_text, \"font\": {\"size\": title_size, \"color\": INK}, \"x\": 0.5, \"y\": 0.97},\n    xaxis={\n        \"title\": {\"text\": \"Unemployment Rate (%)\", \"font\": {\"size\": 12, \"color\": INK}},\n        \"tickfont\": {\"size\": 10, \"color\": INK_SOFT},\n        \"showgrid\": True,\n        \"gridcolor\": GRID,\n        \"gridwidth\": 1,\n        \"griddash\": \"dot\",\n        \"zeroline\": False,\n        \"showline\": False,\n        \"linecolor\": INK_SOFT,\n        \"zerolinecolor\": INK_SOFT,\n    },\n    yaxis={\n        \"title\": {\"text\": \"Inflation Rate (%)\", \"font\": {\"size\": 12, \"color\": INK}},\n        \"tickfont\": {\"size\": 10, \"color\": INK_SOFT},\n        \"showgrid\": True,\n        \"gridcolor\": GRID,\n        \"gridwidth\": 1,\n        \"griddash\": \"dot\",\n        \"zeroline\": False,\n        \"showline\": False,\n        \"linecolor\": INK_SOFT,\n        \"zerolinecolor\": INK_SOFT,\n    },\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    font={\"color\": INK},\n    template=\"plotly_white\",\n    margin={\"l\": 80, \"r\": 100, \"t\": 80, \"b\": 60},\n)\n\n# Save\nfig.write_image(f\"plot-{THEME}.png\", width=800, height=450, scale=4)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}