# How to draw one-line Venn diagram?

This is the a list of set.

data = {{"A"}, {"J"}, {"Q"}, {"G", "H"}, {"I", "O"},
{"B", "C", "E", "F", "K", "N", "P"},
{"B", "C", "D", "E", "F", "K", "L", "M", "P"}}


If the name order from left to right is roughly A O I L D M E B C P K F N J H G Q, how to draw one-line Venn diragram like these?

Ps: Because the elements in the same set need to be gathered together, some adjustments may be needed to the position of the name. In this example, P K F is adjusted to F P K.

The approximate style(not using these data) is as follows

• If the first sublist is {"A", "Q"}, how should the venn diagram be drawn? Aug 5, 2020 at 7:59
• @xzczd Since the data and reference positions are both generated by another program and they have roughly the same index order, this will not happen. Therefore, the first sublist is {"A", "Q"} will not happen Aug 10, 2020 at 1:59
• Then if 2nd list is {"O", "I", "E"}, how should the venn diagram be drawn? Aug 10, 2020 at 2:37
• @xzczd Oh, the plot could not be drawn. Assuming the data can make a diagram of one-line, the question I ask is valid, so this visualization may not be very useful. Aug 10, 2020 at 13:48

ref = StringSplit["A O I L D M E B C P K F N J H G Q"];

pos = PositionIndex[ref];

sorteddata = SortBy[pos@*First][SortBy[pos] /@ data];

Graphics[{Text[Style[#, 32], Append[pos@#, 0]] & /@ ref,
MapThread[{ Opacity[.5], #2, Disk[Append[Mean[pos /@ #], 0], {Length[#]/2, 1}]} &,
{sorteddata, ColorData[97] /@ Range[Length@data]}]}]


Alternatively,

Graphics[{Text[Style[#, FontSize -> Scaled[.05]], Append[pos@#, 0]] & /@ ref,
AbsoluteThickness[35], Line[Thread[{Flatten[MinMax[pos /@ #]], 0}]]} &,
{sorteddata, ColorData[97] /@ Range[Length@data]}]},
ImageSize -> 600]


Here's one way, which wraps elements in nested colored Frames depending on their set membership. It's not the prettiest, but it's easy and handles non-contiguous intersections straightforwardly.

data = {{"A"}, {"J"}, {"Q"}, {"G", "H"}, {"I", "O"}, {"B", "C", "E",
"F", "K", "N", "P"}, {"B", "C", "D", "E", "F", "K", "L", "M", "P"}};

elements = "A O I L D M E B C P K F N J H G Q" // StringSplit;