pythonvenn-diagrammatplotlib-venn

How to show the diagram contents of a Venn diagram


I have the working code below.

from matplotlib import pyplot as plt
import numpy as np
from matplotlib_venn import venn3, venn3_circles
Gastric_tumor_promoters = set(['DPEP1', 'CDC42BPA', 'GNG4', 'RAPGEFL1', 'MYH7B', 'SLC13A3', 'PHACTR3', 'SMPX', 'NELL2', 'PNMAL1', 'KRT23', 'PCP4', 'LOX', 'CDC42BPA'])

Ovarian_tumor_promoters = set(['ABLIM1','CDC42BPA','VSNL1','LOX','PCP4','SLC13A3'])

Gastric_tumor_suppressors = set(['PLCB4', 'VSNL1', 'TOX3', 'VAV3'])
#Ovarian_tumor_suppressors = set(['VAV3', 'FREM2', 'MYH7B', 'RAPGEFL1', 'SMPX', 'TOX3'])
venn3([Gastric_tumor_promoters,Ovarian_tumor_promoters, Gastric_tumor_suppressors], ('GCPromoters', 'OCPromoters', 'GCSuppressors'))

venn3([Gastric_tumor_promoters,Ovarian_tumor_promoters, Gastric_tumor_suppressors], ('GCPromoters', 'OCPromoters', 'GCSuppressors'))
plt.show()

How can I show the contents of each of the set in these 3 circles? With the color alpha being 0.6. Circles must be bigger to accommodate all the symbols.


Solution

  • I'm not sure there is a simple way to do this automatically for any possible combination of sets. If you're ready to do some manual tuning in your particular example, start with something like that:

    A = set(['DPEP1', 'CDC42BPA', 'GNG4', 'RAPGEFL1', 'MYH7B', 'SLC13A3', 'PHACTR3', 'SMPX', 'NELL2', 'PNMAL1', 'KRT23', 'PCP4', 'LOX', 'CDC42BPA'])
    B = set(['ABLIM1','CDC42BPA','VSNL1','LOX','PCP4','SLC13A3'])
    C = set(['PLCB4', 'VSNL1', 'TOX3', 'VAV3'])
    
    v = venn3([A,B,C], ('GCPromoters', 'OCPromoters', 'GCSuppressors'))
    
    v.get_label_by_id('100').set_text('\n'.join(A-B-C))
    v.get_label_by_id('110').set_text('\n'.join(A&B-C))
    v.get_label_by_id('011').set_text('\n'.join(B&C-A))
    v.get_label_by_id('001').set_text('\n'.join(C-A-B))
    v.get_label_by_id('010').set_text('')
    plt.annotate(',\n'.join(B-A-C), xy=v.get_label_by_id('010').get_position() +
                 np.array([0, 0.2]), xytext=(-20,40), ha='center',
                 textcoords='offset points', 
                 bbox=dict(boxstyle='round,pad=0.5', fc='gray', alpha=0.1),
                 arrowprops=dict(arrowstyle='->',              
                                 connectionstyle='arc',color='gray'))
    

    Note that methods like v.get_label_by_id('001') return the matplotlib Text objects, and you are free to configure them to your liking (e.g. you can change font size by calling set_fontsize(8), etc).