{"spec_id":"logistic-regression","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nlogistic-regression: Logistic Regression Curve Plot\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 93/100 | Updated: 2026-05-18\n\"\"\"\n\nimport os\nimport sys\n\n\n# Remove current directory from path to avoid importing local plotly.py\nsys.path = [p for p in sys.path if p not in (\"\", \".\", os.path.dirname(__file__))]\n\nimport numpy as np\nimport plotly.graph_objects as go\nfrom sklearn.linear_model import LogisticRegression\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\"\n\n# Okabe-Ito palette\nBRAND = \"#009E73\"  # First series - bluish green\nACCENT = \"#C475FD\"  # Second series - vermillion\n\n# Data - medical biomarker vs disease diagnosis\nnp.random.seed(42)\nn_samples = 150\n\n# Generate biomarker values (e.g., cholesterol, glucose level)\nbiomarker = np.concatenate(\n    [\n        np.random.normal(150, 25, n_samples // 2),  # Patients without disease\n        np.random.normal(220, 30, n_samples // 2),  # Patients with disease\n    ]\n)\nbiomarker = np.clip(biomarker, 80, 300)\n\n# Binary outcome (0=no disease, 1=disease present)\ny = np.array([0] * (n_samples // 2) + [1] * (n_samples // 2))\n\n# Shuffle data\nshuffle_idx = np.random.permutation(len(biomarker))\nbiomarker = biomarker[shuffle_idx]\ny = y[shuffle_idx]\n\n# Fit logistic regression\nX = biomarker.reshape(-1, 1)\nmodel = LogisticRegression()\nmodel.fit(X, y)\n\n# Generate smooth curve for predictions\nx_curve = np.linspace(80, 300, 200)\ny_proba = model.predict_proba(x_curve.reshape(-1, 1))[:, 1]\n\n# Calculate confidence intervals (approximate using standard error)\nse = np.sqrt(y_proba * (1 - y_proba) / n_samples) * 1.96\ny_upper = np.clip(y_proba + se, 0, 1)\ny_lower = np.clip(y_proba - se, 0, 1)\n\n# Jitter y values for visibility (constrained to [0, 1])\ny_jittered = y + np.random.uniform(-0.02, 0.02, len(y))\ny_jittered = np.clip(y_jittered, 0, 1)\n\n# Model accuracy\naccuracy = model.score(X, y)\n\n# Create figure\nfig = go.Figure()\n\n# Confidence interval band\nfig.add_trace(\n    go.Scatter(\n        x=np.concatenate([x_curve, x_curve[::-1]]),\n        y=np.concatenate([y_upper, y_lower[::-1]]),\n        fill=\"toself\",\n        fillcolor=\"rgba(0, 158, 115, 0.2)\",\n        line={\"color\": \"rgba(0,0,0,0)\"},\n        name=\"95% CI\",\n        showlegend=True,\n        hoverinfo=\"skip\",\n    )\n)\n\n# Logistic regression curve\nfig.add_trace(\n    go.Scatter(\n        x=x_curve,\n        y=y_proba,\n        mode=\"lines\",\n        line={\"color\": BRAND, \"width\": 4},\n        name=\"Logistic Curve\",\n        hovertemplate=\"<b>Biomarker:</b> %{x:.1f}<br><b>Probability:</b> %{y:.3f}<extra></extra>\",\n    )\n)\n\n# Decision threshold line at 0.5\nfig.add_trace(\n    go.Scatter(\n        x=[80, 300],\n        y=[0.5, 0.5],\n        mode=\"lines\",\n        line={\"color\": INK_SOFT, \"width\": 2, \"dash\": \"dash\"},\n        name=\"Decision Threshold (0.5)\",\n        hoverinfo=\"skip\",\n    )\n)\n\n# Data points - Class 0 (No Disease)\nmask_0 = y == 0\nfig.add_trace(\n    go.Scatter(\n        x=biomarker[mask_0],\n        y=y_jittered[mask_0],\n        mode=\"markers\",\n        marker={\"size\": 12, \"color\": BRAND, \"opacity\": 0.6, \"line\": {\"width\": 1, \"color\": PAGE_BG}},\n        name=\"No Disease (0)\",\n        hovertemplate=\"<b>Biomarker:</b> %{x:.1f}<br><b>Outcome:</b> No Disease<extra></extra>\",\n    )\n)\n\n# Data points - Class 1 (Disease Present)\nmask_1 = y == 1\nfig.add_trace(\n    go.Scatter(\n        x=biomarker[mask_1],\n        y=y_jittered[mask_1],\n        mode=\"markers\",\n        marker={\"size\": 12, \"color\": ACCENT, \"opacity\": 0.6, \"line\": {\"width\": 1, \"color\": PAGE_BG}},\n        name=\"Disease Present (1)\",\n        hovertemplate=\"<b>Biomarker:</b> %{x:.1f}<br><b>Outcome:</b> Disease Present<extra></extra>\",\n    )\n)\n\n# Layout\nfig.update_layout(\n    title={\n        \"text\": \"logistic-regression · python · plotly · anyplot.ai\",\n        \"font\": {\"size\": 28, \"color\": INK},\n        \"x\": 0.5,\n        \"xanchor\": \"center\",\n    },\n    xaxis={\n        \"title\": {\"text\": \"Biomarker Level (mg/dL)\", \"font\": {\"size\": 22, \"color\": INK}},\n        \"tickfont\": {\"size\": 18, \"color\": INK_SOFT},\n        \"range\": [75, 305],\n        \"gridcolor\": \"rgba(26,26,23,0.10)\" if THEME == \"light\" else \"rgba(240,239,232,0.10)\",\n        \"gridwidth\": 1,\n        \"linecolor\": INK_SOFT,\n        \"zerolinecolor\": INK_SOFT,\n    },\n    yaxis={\n        \"title\": {\"text\": \"Disease Probability\", \"font\": {\"size\": 22, \"color\": INK}},\n        \"tickfont\": {\"size\": 18, \"color\": INK_SOFT},\n        \"range\": [-0.05, 1.05],\n        \"gridcolor\": \"rgba(26,26,23,0.10)\" if THEME == \"light\" else \"rgba(240,239,232,0.10)\",\n        \"gridwidth\": 1,\n        \"linecolor\": INK_SOFT,\n        \"zerolinecolor\": INK_SOFT,\n    },\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    font={\"color\": INK},\n    legend={\n        \"font\": {\"size\": 16, \"color\": INK_SOFT},\n        \"x\": 0.02,\n        \"y\": 0.98,\n        \"bgcolor\": ELEVATED_BG,\n        \"bordercolor\": INK_SOFT,\n        \"borderwidth\": 1,\n    },\n    annotations=[\n        {\n            \"x\": 265,\n            \"y\": 0.15,\n            \"text\": f\"Accuracy: {accuracy:.1%}\",\n            \"showarrow\": False,\n            \"font\": {\"size\": 18, \"color\": INK},\n            \"bgcolor\": ELEVATED_BG,\n            \"bordercolor\": INK_SOFT,\n            \"borderwidth\": 1,\n            \"borderpad\": 6,\n        }\n    ],\n    margin={\"l\": 80, \"r\": 60, \"t\": 100, \"b\": 80},\n)\n\n# Save as PNG (4800x2700)\nfig.write_image(f\"plot-{THEME}.png\", width=1600, height=900, scale=3)\n\n# Save interactive HTML\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}