{"spec_id":"roc-curve","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nroc-curve: ROC Curve with AUC\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 94/100 | Updated: 2026-05-09\n\"\"\"\n\nimport os\nimport sys\n\nimport numpy as np\nimport pandas as pd\n\n\n# Prevent import of local file by removing current dir from path\nsys.path = [p for p in sys.path if os.path.abspath(p) != os.path.dirname(os.path.abspath(__file__))]\n\nfrom plotnine import (\n    aes,\n    annotate,\n    coord_fixed,\n    element_line,\n    element_rect,\n    element_text,\n    geom_abline,\n    geom_line,\n    ggplot,\n    labs,\n    scale_color_manual,\n    scale_x_continuous,\n    scale_y_continuous,\n    theme,\n    theme_minimal,\n)\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\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\", \"#954477\"]\n\n# Data - Simulate ROC curve from good and moderate classifiers\nnp.random.seed(42)\n\nn_points = 200\nthresholds = np.linspace(0, 1, n_points)\n\n# Model 1: Good classifier (AUC ~ 0.92)\nfpr_1 = np.sort(np.concatenate([[0], np.power(thresholds[1:-1], 2.5), [1]]))\ntpr_1 = np.sort(np.concatenate([[0], np.power(thresholds[1:-1], 0.4), [1]]))\n\n# Model 2: Moderate classifier (AUC ~ 0.78)\nfpr_2 = np.sort(np.concatenate([[0], np.power(thresholds[1:-1], 1.8), [1]]))\ntpr_2 = np.sort(np.concatenate([[0], np.power(thresholds[1:-1], 0.7), [1]]))\n\n# Calculate AUC using trapezoidal rule\nauc_1 = np.trapezoid(tpr_1, fpr_1)\nauc_2 = np.trapezoid(tpr_2, fpr_2)\n\n# Create DataFrame for plotting\ndf = pd.DataFrame(\n    {\n        \"fpr\": np.concatenate([fpr_1, fpr_2]),\n        \"tpr\": np.concatenate([tpr_1, tpr_2]),\n        \"Model\": [f\"Random Forest (AUC = {auc_1:.2f})\"] * len(fpr_1)\n        + [f\"Logistic Regression (AUC = {auc_2:.2f})\"] * len(fpr_2),\n    }\n)\n\n# Theme-adaptive style\nanyplot_theme = theme(\n    figure_size=(12, 12),\n    plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    panel_background=element_rect(fill=PAGE_BG),\n    panel_grid_major=element_line(color=INK, size=0.3, alpha=0.10),\n    panel_grid_minor=element_line(color=INK, size=0.2, alpha=0.05),\n    panel_border=element_rect(color=INK_SOFT, fill=None, size=0.5),\n    axis_title=element_text(size=20, color=INK),\n    axis_text=element_text(size=16, color=INK_SOFT),\n    axis_line=element_line(color=INK_SOFT),\n    plot_title=element_text(size=24, color=INK),\n    legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT, size=0.5),\n    legend_text=element_text(size=16, color=INK_SOFT),\n    legend_title=element_text(size=18, color=INK),\n    legend_position=(0.65, 0.25),\n)\n\n# Create plot\nplot = (\n    ggplot(df, aes(x=\"fpr\", y=\"tpr\", color=\"Model\"))\n    + geom_abline(intercept=0, slope=1, linetype=\"dashed\", color=INK_SOFT, size=1, alpha=0.5)\n    + geom_line(size=2.5, alpha=0.9)\n    + scale_color_manual(values=IMPRINT[:2])\n    + scale_x_continuous(limits=(0, 1), breaks=np.arange(0, 1.1, 0.2))\n    + scale_y_continuous(limits=(0, 1), breaks=np.arange(0, 1.1, 0.2))\n    + coord_fixed(ratio=1)\n    + labs(x=\"False Positive Rate\", y=\"True Positive Rate\", title=\"roc-curve · plotnine · anyplot.ai\", color=\"Model\")\n    + theme_minimal()\n    + anyplot_theme\n    + annotate(\"text\", x=0.6, y=0.1, label=\"Diagonal = Random Classifier\", size=12, color=INK_SOFT, fontstyle=\"italic\")\n)\n\n# Save plot\nplot.save(f\"plot-{THEME}.png\", dpi=300, width=12, height=12)\n"}