Skip to main content
4 of 4
added 1184 characters in body

Edit 02

There was a small bug in dealing with empty sets (e.g. the one that arises with the chosen random seed below). This is now fixed. Additionally, figured I'd play around with the new-ish HardcorePointProcess functionality to get more evenly-spaced labels:

shrinkPolygon[polygon_,sf_:0.85] := TransformedRegion[polygon,ScalingTransform[{sf, sf}, RegionCentroid[polygon]]]

postProcessVennDiagram[vd_] := 
 Block[{labels, polygons, rpts, text, r0, hs},
  labels = vd[[2, All, 2, 1, 1, 1, 1]];
  r0 = 2/(Sqrt[n] Sqrt[\[Pi]]) /. n -> Length[Join @@ labels];
  hs = HardcorePointProcess[1000, r0, 2];
  polygons = Cases[vd[[1, 1]], {Null, Polygon[a__]} :> Polygon[a]];
  rpts = MapThread[Take[RandomPointConfiguration[hs, shrinkPolygon[DiscretizeRegion[#1]]]["Points"], #2] &, {polygons, Length /@ labels}];
  text = Graphics[MapThread[Text[Style[#1, 16], #2] &, {Join @@ labels, Join @@ rpts}]];
  Show[vd[[1]], text, ImageSize -> 350]]

postProcessVennDiagram[vd]

enter image description here

Seems to work reasonably well. Note you might have to adjust the radius, r0, and scaling factor, sf, in the polygon shrinking (which I added to ensure the labels are completely maintained inside the regions).

Edit 01

It should be possible to post-process the result to place the elements inside their corresponding region. For example, here I'm using RandomPoint but I suspect you can use some sort of Lloyd relaxation on a voronoi mesh to get them more evenly spaced:

postProcessVennDiagram[vd_] := 
 Block[{labels, length, polygons, rpts, text}, 
  labels = vd[[2, All, 2, 1, 1, 1, 1]];
  polygons = Cases[vd[[1, 1]], {Null, Polygon[a__]} :> Polygon[a]];
  rpts = MapThread[RandomPoint, {polygons, Length /@ labels}];
  text = Graphics[MapThread[Text[Style[#1, 16], #2] &, {Join @@ labels, Join @@ rpts}]];
  Show[vd[[1]], text, ImageSize -> 350]]

postProcessVennDiagram[vd]

enter image description here

Original Answer

There's a very nice Function Repository entry that makes this quite easy:

SeedRandom[25];
vd=With[{
  a = RandomSample[Range[3, 30], 20],
  b = RandomSample[Range[2, 40], 20],
  c = RandomSample[Range[4, 49], 20]
  },
 ResourceFunction["VennDiagram"][{a, b, c}]
 ]

enter image description here