【问题标题】:Python: Venn diagram: how to show the diagram contents?Python:维恩图:如何显示图表内容?
【发布时间】:2017-08-08 21:03:33
【问题描述】:

我有下面的工作代码。

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()

如何在这 3 个圆圈中显示每个集合的内容?颜色 alpha 为 0.6。圆圈必须更大以容纳所有符号。

【问题讨论】:

    标签: python-3.5 venn-diagram matplotlib-venn


    【解决方案1】:

    我不确定是否有一种简单的方法可以针对任何可能的集合组合自动执行此操作。如果您准备在您的特定示例中进行一些手动调整,请从以下内容开始:

    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'))
    

    请注意,v.get_label_by_id('001') 之类的方法会返回 matplotlib Text 对象,您可以根据自己的喜好随意配置它们(例如,您可以通过调用 set_fontsize(8) 等来更改字体大小)。

    【讨论】:

      【解决方案2】:

      这是一个自动化整个事情的例子。它创建一个临时字典,其中包含 venn 所需的 id 作为键以及该 id 的所有参与集的交集。

      如果您不想对标签进行排序,请删除倒数第二行中的 sorted() 调用。

      import math
      from matplotlib import pyplot as plt
      from matplotlib_venn import venn2, venn3
      import numpy as np
      
      # Convert number to indices into binary
      # e.g. 5 -> '101' > [2, 0]
      def bits2indices(b):
          l = []
          if b == 0:
              return l
          for i in reversed(range(0, int(math.log(b, 2)) + 1)):
              if b & (1 << i):
                  l.append(i)
          return l
      
      # Make dictionary containing venn id's and set intersections
      # e.g. d = {'100': {'c', 'b', 'a'}, '010': {'c', 'd', 'e'}, ... }
      def set2dict(s):
          d = {}
          for i in range(1, 2**len(s)):
              # Make venn id strings
              key = bin(i)[2:].zfill(len(s))
              key = key[::-1]
              ind = bits2indices(i)
              # Get the participating sets for this id
              participating_sets = [s[x] for x in ind] 
              # Get the intersections of those sets
              inter = set.intersection(*participating_sets)
              d[key] = inter
          return d
      
      # Define some sets
      a = set(['a', 'b', 'c']) 
      b = set(['c', 'd', 'e'])
      c = set(['e', 'f', 'a'])
      s = [a, b, c]
      
      # Create dictionary from sets
      d = set2dict(s)
      
      # Plot it
      h = venn3(s, ('A', 'B', 'C'))
      for k, v in d.items():
          l = h.get_label_by_id(k)
          if l:
              l.set_text('\n'.join(sorted(v)))
      plt.show()
      

      /编辑 对不起,我刚刚发现上面的代码没有删除重复的标签,因此是错误的。 venn 显示的元素数量和标签数量不同。这是一个新版本,它从其他交叉路口删除了错误的重复项。我想有一种更聪明、更实用的方法可以做到这一点,而不是对所有交叉点进行两次迭代......

      import math, itertools
      from matplotlib import pyplot as plt
      from matplotlib_venn import venn2, venn3
      import numpy as np
      
      # Generate list index for itertools combinations
      def gen_index(n):
          x = -1
          while True:       
              while True:
                  x = x + 1
                  if bin(x).count('1') == n:
                      break
              yield x
      
      # Generate all combinations of intersections
      def make_intersections(sets):
          l = [None] * 2**len(sets)
          for i in range(1, len(sets) + 1):
              ind = gen_index(i)
              for subset in itertools.combinations(sets, i):
                  inter = set.intersection(*subset)
                  l[next(ind)] = inter
          return l
      
      # Get weird reversed binary string id for venn
      def number2venn_id(x, n_fill):
          id = bin(x)[2:].zfill(n_fill)
          id = id[::-1]
          return id
      
      # Iterate over all combinations and remove duplicates from intersections with
      # more sets
      def sets2dict(sets):
          l = make_intersections(sets)
          d = {}
          for i in range(1, len(l)):
              d[number2venn_id(i, len(sets))] = l[i]
              for j in range(1, len(l)):
                  if bin(j).count('1') < bin(i).count('1'):
                      l[j] = l[j] - l[i]
                      d[number2venn_id(j, len(sets))] = l[j] - l[i]
          return d
      
      # Define some sets
      a = set(['a', 'b', 'c', 'f']) 
      b = set(['c', 'd', 'e'])
      c = set(['e', 'f', 'a'])
      sets = [a, b, c]
      
      d = sets2dict(sets)
      
      # Plot it
      h = venn3(sets, ('A', 'B', 'C'))
      for k, v in d.items():
         l = h.get_label_by_id(k)
         if l:
             l.set_fontsize(12)
             l.set_text('\n'.join(sorted(v)))
      
      # Original for comparison
      f = plt.figure(2)
      venn3(sets, ('A', 'B', 'C'))  
      plt.show()
      

      【讨论】:

        【解决方案3】:

        感谢自动化,@Vinci!我想知道您(或其他人)是否编写了一个重新排列内容的版本,以便元素以随机方式留在气泡中而不是一长串? ...奖励曲目:如果元素不适合,请重新确定气泡的尺寸? ;)

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-24
        相关资源
        最近更新 更多