Venn3: How to reposition circles and labels?

2019-03-30 21:05发布

问题:

I have made a three way venn diagram. I have three issues with it that I can't seem to solve.

  1. What is the code to move the circle labels (i.e."Set1","Set2","Set3") because right now one is too far away from the circle.

  2. What is the code to make the circles be three equal sizes/change the circle size?

  3. What is the code to move the circles around the plot. Right now, set2 is within set3 (but coloured differently), I would like the diagram to look more like the "standard" way of showing a venn diagram (i.e. 3 separate circles with some overlap in the middle).

On another note, I found it difficult to find what the commands such as "set_x", "set_alpha" should be; if anyone knew of a manual that would answer by above questions I would appreciate it, I couldn't seem to find one place with all the information I needed.

import sys
import numpy
import scipy
from matplotlib_venn import venn3,venn3_circles
from matplotlib import pyplot as plt

#Build three lists to make 3 way venn diagram with                                                                                                                             
list_line = lambda x: set([line.strip() for line in open(sys.argv[x])])
set1,set2,set3 = list_line(1),list_line(2),list_line(3)

#Make venn diagram                                                                                                                                                             
vd = venn3([set1,set2,set3],set_labels=("Set1","Set2","Set3"))

#Colours: get the HTML codes from the net                                                                                                                                      
vd.get_patch_by_id("100").set_color("#FF8000")
vd.get_patch_by_id("001").set_color("#5858FA")
vd.get_patch_by_id("011").set_color("#01DF3A")

#Move the numbers in the circles                                                                                                                                               
vd.get_label_by_id("100").set_x(-0.55)
vd.get_label_by_id("011").set_x(0.1)

#Strength of color, 2.0 is very strong.                                                                                                                                        
vd.get_patch_by_id("100").set_alpha(0.8)
vd.get_patch_by_id("001").set_alpha(0.6)
vd.get_patch_by_id("011").set_alpha(0.8)

plt.title("Venn Diagram",fontsize=14)
plt.savefig("output",format="pdf")

回答1:

What is the code to move the circle labels (i.e."Set1","Set2","Set3") because right now one is too far away from the circle.

Something like that:

lbl = vd.get_label_by_id("A")
x, y = lbl.get_position()
lbl.set_position((x+0.1, y-0.2))  # Or whatever

The "A", "B", and "C" are predefined identifiers, denoting the three sets.

What is the code to make the circles be three equal sizes/change the circle size?

If you do not want the circle/region sizes to correspond to your data (not necessarily a good idea), you can get an unweighted ("classical") Venn diagram using the function venn3_unweighted:

from matplotlib_venn import venn3_unweighted 
venn3_unweighted(...same parameters you used in venn3...)

You can further cheat and tune the result by providing a subset_areas parameter to venn3_unweighted - this is a seven-element vector specifying the desired relative size of each region. In this case the diagram will be drawn as if the region areas were subset_areas, yet the numbers will be shown from the actual subsets. Try, for example:

venn3_unweighted(...., subset_areas=(10,1,1,1,1,1,1))

What is the code to move the circles around the plot.

The need to "move the circles around" is somewhat unusual - normally you would either want the circles to be positioned so that their intersection sizes correspond to your data, or use the "default" positioning. The functions venn3 and venn3_unweighted cater to those two requirements. Moving circles around arbitrarily is possible, but would require some lower-level coding and I'd advice against that.

I found it difficult to find what the commands such as "set_x", "set_alpha" should be

The object you get when you call v.get_label_by_id is a Matplotlib Text object. You can read about its methods and properties here. The object returned by v.get_patch_by_id is a PathPatch, look here and here for reference.