{"spec_id":"venn-basic","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nvenn-basic: Venn Diagram\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-11\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import *\n\n\nnp.random.seed(42)\n\nLetsPlot.setup_html()\n\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\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\", \"#954477\"]\n\n# Data: Three research fields with overlapping expertise\nset_a_label = \"Machine Learning\"\nset_b_label = \"Statistics\"\nset_c_label = \"Data Engineering\"\n\n# Set sizes and intersections\nonly_a = 45\nonly_b = 35\nonly_c = 30\nab_only = 25\nac_only = 15\nbc_only = 20\nabc = 10\n\n# Circle parameters (for 3-set Venn diagram)\nr = 1.8\ncx_a, cy_a = -0.85, 0.6\ncx_b, cy_b = 0.85, 0.6\ncx_c, cy_c = 0.0, -0.75\n\n# Generate circle points\ntheta = np.linspace(0, 2 * np.pi, 100)\n\n# Create circle data\ncircle_a_x = cx_a + r * np.cos(theta)\ncircle_a_y = cy_a + r * np.sin(theta)\ncircle_b_x = cx_b + r * np.cos(theta)\ncircle_b_y = cy_b + r * np.sin(theta)\ncircle_c_x = cx_c + r * np.cos(theta)\ncircle_c_y = cy_c + r * np.sin(theta)\n\n# Create DataFrames for circles\ndf_a = pd.DataFrame({\"x\": circle_a_x, \"y\": circle_a_y, \"set\": set_a_label})\ndf_b = pd.DataFrame({\"x\": circle_b_x, \"y\": circle_b_y, \"set\": set_b_label})\ndf_c = pd.DataFrame({\"x\": circle_c_x, \"y\": circle_c_y, \"set\": set_c_label})\ndf_circles = pd.concat([df_a, df_b, df_c], ignore_index=True)\n\n# Label positions and values\nlabels_data = pd.DataFrame(\n    {\n        \"x\": [cx_a - 0.6, cx_b + 0.6, cx_c, (cx_a + cx_b) / 2, (cx_a + cx_c) / 2 - 0.35, (cx_b + cx_c) / 2 + 0.35, 0.0],\n        \"y\": [cy_a + 0.4, cy_b + 0.4, cy_c - 0.75, cy_a + 0.75, (cy_a + cy_c) / 2 - 0.4, (cy_b + cy_c) / 2 - 0.4, 0.0],\n        \"label\": [str(only_a), str(only_b), str(only_c), str(ab_only), str(ac_only), str(bc_only), str(abc)],\n    }\n)\n\n# Set name labels (outside circles)\nset_labels_data = pd.DataFrame(\n    {\n        \"x\": [cx_a - 0.9, cx_b + 0.9, cx_c],\n        \"y\": [cy_a + 1.5, cy_b + 1.5, cy_c - 1.6],\n        \"label\": [set_a_label, set_b_label, set_c_label],\n    }\n)\n\n# Map sets to Okabe-Ito palette\nset_colors = {set_a_label: IMPRINT[0], set_b_label: IMPRINT[1], set_c_label: IMPRINT[2]}\n\n# Create custom theme for chrome styling\nanyplot_theme = theme(\n    plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    panel_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    axis_title=element_text(color=INK),\n    axis_text=element_text(color=INK_SOFT),\n    axis_line=element_blank(),\n    plot_title=element_text(size=28, face=\"bold\", hjust=0.5, color=INK),\n    legend_position=\"none\",\n    plot_margin=[50, 30, 30, 30],\n)\n\n# Create plot\nplot = (\n    ggplot()\n    + geom_polygon(aes(x=\"x\", y=\"y\", fill=\"set\"), data=df_circles, alpha=0.35, color=INK_SOFT, size=2.5)\n    + geom_text(aes(x=\"x\", y=\"y\", label=\"label\"), data=labels_data, size=20, fontface=\"bold\", color=INK)\n    + geom_text(aes(x=\"x\", y=\"y\", label=\"label\"), data=set_labels_data, size=18, fontface=\"bold\", color=INK)\n    + scale_fill_manual(values=set_colors)\n    + coord_fixed(ratio=1)\n    + labs(title=\"venn-basic · letsplot · anyplot.ai\")\n    + theme_void()\n    + anyplot_theme\n    + ggsize(1200, 1200)\n)\n\n# Save as PNG and HTML with theme suffix\nggsave(plot, f\"plot-{THEME}.png\", scale=3)\nggsave(plot, f\"plot-{THEME}.html\")\n\n# Move files from lets-plot-images subdirectory if needed\nif os.path.exists(f\"lets-plot-images/plot-{THEME}.png\"):\n    os.rename(f\"lets-plot-images/plot-{THEME}.png\", f\"plot-{THEME}.png\")\nif os.path.exists(f\"lets-plot-images/plot-{THEME}.html\"):\n    os.rename(f\"lets-plot-images/plot-{THEME}.html\", f\"plot-{THEME}.html\")\nif os.path.exists(\"lets-plot-images\") and not os.listdir(\"lets-plot-images\"):\n    os.rmdir(\"lets-plot-images\")\n"}