|
| 1 | +""" pyplots.ai |
| 2 | +venn-basic: Venn Diagram |
| 3 | +Library: letsplot 4.8.2 | Python 3.13.11 |
| 4 | +Quality: 91/100 | Created: 2025-12-29 |
| 5 | +""" |
| 6 | + |
| 7 | +import os |
| 8 | + |
| 9 | +import numpy as np |
| 10 | +import pandas as pd |
| 11 | +from lets_plot import * |
| 12 | + |
| 13 | + |
| 14 | +np.random.seed(42) |
| 15 | + |
| 16 | +LetsPlot.setup_html() |
| 17 | + |
| 18 | +# Data: Three research fields with overlapping expertise |
| 19 | +set_a_label = "Machine Learning" |
| 20 | +set_b_label = "Statistics" |
| 21 | +set_c_label = "Data Engineering" |
| 22 | + |
| 23 | +# Set sizes and intersections |
| 24 | +only_a = 45 # Only ML |
| 25 | +only_b = 35 # Only Statistics |
| 26 | +only_c = 30 # Only Data Engineering |
| 27 | +ab_only = 25 # ML & Statistics (not DE) |
| 28 | +ac_only = 15 # ML & DE (not Stats) |
| 29 | +bc_only = 20 # Stats & DE (not ML) |
| 30 | +abc = 10 # All three |
| 31 | + |
| 32 | +# Circle parameters (for 3-set Venn diagram) - larger for better canvas utilization |
| 33 | +r = 1.8 # radius (increased from 1.5) |
| 34 | +cx_a, cy_a = -0.85, 0.6 # Center of set A (top left) |
| 35 | +cx_b, cy_b = 0.85, 0.6 # Center of set B (top right) |
| 36 | +cx_c, cy_c = 0.0, -0.75 # Center of set C (bottom) |
| 37 | + |
| 38 | +# Generate circle points |
| 39 | +theta = np.linspace(0, 2 * np.pi, 100) |
| 40 | + |
| 41 | +# Create circle data |
| 42 | +circle_a_x = cx_a + r * np.cos(theta) |
| 43 | +circle_a_y = cy_a + r * np.sin(theta) |
| 44 | +circle_b_x = cx_b + r * np.cos(theta) |
| 45 | +circle_b_y = cy_b + r * np.sin(theta) |
| 46 | +circle_c_x = cx_c + r * np.cos(theta) |
| 47 | +circle_c_y = cy_c + r * np.sin(theta) |
| 48 | + |
| 49 | +# Create DataFrames for circles |
| 50 | +df_a = pd.DataFrame({"x": circle_a_x, "y": circle_a_y, "set": set_a_label}) |
| 51 | +df_b = pd.DataFrame({"x": circle_b_x, "y": circle_b_y, "set": set_b_label}) |
| 52 | +df_c = pd.DataFrame({"x": circle_c_x, "y": circle_c_y, "set": set_c_label}) |
| 53 | +df_circles = pd.concat([df_a, df_b, df_c], ignore_index=True) |
| 54 | + |
| 55 | +# Label positions and values (adjusted for larger circles and better spacing) |
| 56 | +labels_data = pd.DataFrame( |
| 57 | + { |
| 58 | + "x": [ |
| 59 | + cx_a - 0.6, # Only A (left side of A) |
| 60 | + cx_b + 0.6, # Only B (right side of B) |
| 61 | + cx_c, # Only C (bottom of C) - moved further down |
| 62 | + (cx_a + cx_b) / 2, # A & B intersection |
| 63 | + (cx_a + cx_c) / 2 - 0.35, # A & C intersection |
| 64 | + (cx_b + cx_c) / 2 + 0.35, # B & C intersection |
| 65 | + 0.0, # Center (A & B & C) |
| 66 | + ], |
| 67 | + "y": [ |
| 68 | + cy_a + 0.4, # Only A |
| 69 | + cy_b + 0.4, # Only B |
| 70 | + cy_c - 0.75, # Only C - moved much further down to avoid center overlap |
| 71 | + cy_a + 0.75, # A & B intersection |
| 72 | + (cy_a + cy_c) / 2 - 0.4, # A & C intersection |
| 73 | + (cy_b + cy_c) / 2 - 0.4, # B & C intersection |
| 74 | + 0.0, # Center (A & B & C) |
| 75 | + ], |
| 76 | + "label": [str(only_a), str(only_b), str(only_c), str(ab_only), str(ac_only), str(bc_only), str(abc)], |
| 77 | + } |
| 78 | +) |
| 79 | + |
| 80 | +# Set name labels (outside circles) - adjusted for larger circles |
| 81 | +set_labels_data = pd.DataFrame( |
| 82 | + { |
| 83 | + "x": [cx_a - 0.9, cx_b + 0.9, cx_c], |
| 84 | + "y": [cy_a + 1.5, cy_b + 1.5, cy_c - 1.6], |
| 85 | + "label": [set_a_label, set_b_label, set_c_label], |
| 86 | + } |
| 87 | +) |
| 88 | + |
| 89 | +# Colors |
| 90 | +colors = {"Machine Learning": "#306998", "Statistics": "#FFD43B", "Data Engineering": "#DC2626"} |
| 91 | + |
| 92 | +# Create plot |
| 93 | +plot = ( |
| 94 | + ggplot() |
| 95 | + + geom_polygon(aes(x="x", y="y", fill="set"), data=df_circles, alpha=0.35, color="white", size=2.5) |
| 96 | + + geom_text(aes(x="x", y="y", label="label"), data=labels_data, size=20, fontface="bold", color="#1a1a1a") |
| 97 | + + geom_text(aes(x="x", y="y", label="label"), data=set_labels_data, size=18, fontface="bold", color="#222222") |
| 98 | + + scale_fill_manual(values=colors) |
| 99 | + + coord_fixed(ratio=1) |
| 100 | + + labs(title="venn-basic · lets-plot · pyplots.ai") |
| 101 | + + theme_void() |
| 102 | + + theme( |
| 103 | + plot_title=element_text(size=28, face="bold", hjust=0.5), legend_position="none", plot_margin=[50, 30, 30, 30] |
| 104 | + ) |
| 105 | + + ggsize(1200, 1200) |
| 106 | +) |
| 107 | + |
| 108 | +# Save as PNG and HTML |
| 109 | +ggsave(plot, "plot.png", scale=3) |
| 110 | +ggsave(plot, "plot.html") |
| 111 | + |
| 112 | +# Move files from lets-plot-images subdirectory to current directory |
| 113 | +if os.path.exists("lets-plot-images/plot.png"): |
| 114 | + os.rename("lets-plot-images/plot.png", "plot.png") |
| 115 | +if os.path.exists("lets-plot-images/plot.html"): |
| 116 | + os.rename("lets-plot-images/plot.html", "plot.html") |
| 117 | +if os.path.exists("lets-plot-images") and not os.listdir("lets-plot-images"): |
| 118 | + os.rmdir("lets-plot-images") |
0 commit comments