복붙노트

[PYTHON] 3 세트 이상의 비례 다이어그램

PYTHON

3 세트 이상의 비례 다이어그램

MongoDB에는 각각 하나 이상의 카테고리가있는 문서 모음이 있습니다. map reduce를 사용하여 얼마나 많은 문서가 각 범주의 고유 한 조합을 가지고 있는지에 대한 세부 정보를 얻을 수 있습니다.

['cat1']               = 523
['cat2']               = 231
['cat3']               = 102
['cat4']               = 72
['cat1','cat2']        = 710
['cat1','cat3']        = 891
['cat1','cat3','cat4'] = 621 ...

합계는 카테고리의 정확한 조합 인 문서의 수입니다.

이 데이터를 제공하는 합리적인 방법을 찾고 있는데, 비례 영역을 가진 venn 다이어그램이 좋은 아이디어라고 생각합니다. 위의 예를 사용하면 cat1 영역은 523 + 710 + 891 + 621이고 cat1과 cat3 사이의 중첩 영역은 891 + 621이고 cat1, cat3, cat4 사이의 중복 영역은 621이됩니다.

누구든지이 구현에 갈 수있는 방법에 대한 모든 정보가 있습니까? Python (+ Numpy / MatPlotLib) 또는 MatLab에서 수행하는 것이 좋습니다.

해결법

  1. ==============================

    1.상호 연결된 여러 범주의 개체 수를 나타낼 필요가 있고, Venn 다이어그램은 사소한 양의 범주와 그 중첩을 나타낼 수 없습니다.

    상호 연결된 여러 범주의 개체 수를 나타낼 필요가 있고, Venn 다이어그램은 사소한 양의 범주와 그 중첩을 나타낼 수 없습니다.

    각 범주 및 그 조합을 그래프의 노드로 간주하십시오. 노드의 크기가 각 카테고리의 수를 나타내며 모서리가 관련 카테고리를 연결하도록 그래프를 그린다. 이 접근법의 장점은 여러 카테고리를 쉽게 수용 할 수 있으며 연결된 버블 차트 유형이됩니다.

    제안 된 솔루션은 NetworkX를 사용하여 데이터 구조를 만들고 matplotlib을 사용하여 데이터 구조를 그립니다. 데이터가 올바른 형식으로 제공되면 다중 연결을 통해 많은 수의 범주로 확장됩니다.

    import networkx as nx
    import matplotlib.pyplot as plt
    
    def load_nodes():
        text = '''  Node    Size
                    1        523
                    2        231
                    3        102
                    4         72
                    1+2      710
                    1+3      891
                    1+3+4    621'''
        # load nodes into list, discard header
        # this may be replaced by some appropriate output 
        # from your program
        data = text.split('\n')[1:]
        data = [ d.split() for d in data ]
        data = [ tuple([ d[0], 
                        dict( size=int(d[1]) ) 
                        ]) for d in data]
        return data
    
    def load_edges():
        text = '''  From   To
                    1+2    1
                    1+2    2
                    1+3    1
                    1+3    3
                    1+3+4    1
                    1+3+4    3
                    1+3+4    4'''
        # load edges into list, discard header
        # this may be replaced by some appropriate output 
        # from your program
        data = text.split('\n')[1:]
        data = [ tuple( d.split() ) for d in data ]
        return data
    
    if __name__ == '__main__':
        scale_factor = 5
        G = nx.Graph()
        nodes = load_nodes()
        node_sizes = [ n[1]['size']*scale_factor
                      for n in nodes ]
    
        edges = load_edges()
        G.add_edges_from( edges )
    
        nx.draw_networkx(G, 
                         pos=nx.spring_layout(G),
                         node_size = node_sizes)
        plt.axis('off')
        plt.show()
    

    다른 솔루션으로는 버블 차트, 보로 노이 다이어그램, 코드 다이어그램 및 하이브 플롯 등이 있습니다. 링크 된 예제 중 어느 것도 Python을 사용하지 않습니다. 그들은 단지 설명을 목적으로 제시된 것입니다.

  2. ==============================

    2.저는 ninjagecko가 정확하다고 믿습니다. 다이어그램이 n 차원이 아니라면 일반적으로 교차 다이어그램으로 표현할 수 없습니다. 그러나 각 카테고리의 모든 교차점을 보여주는 다이어그램이있는 경우 2D로 표현할 수 있으며이 다이어그램 자체는 단일 다이어그램이 될 수 있습니다. 따라서 이것이 귀하의 데이터를 표현하는보다 적절한 방법 일 수 있습니다. 설명하기 위해 스택 형 바둑판을 만들었습니다.

    저는 ninjagecko가 정확하다고 믿습니다. 다이어그램이 n 차원이 아니라면 일반적으로 교차 다이어그램으로 표현할 수 없습니다. 그러나 각 카테고리의 모든 교차점을 보여주는 다이어그램이있는 경우 2D로 표현할 수 있으며이 다이어그램 자체는 단일 다이어그램이 될 수 있습니다. 따라서 이것이 귀하의 데이터를 표현하는보다 적절한 방법 일 수 있습니다. 설명하기 위해 스택 형 바둑판을 만들었습니다.

    코드:

    cats = ['cat1','cat2','cat3','cat4']
    data = {('cat1',): 523, ('cat2',): 231, ('cat3',): 102, ('cat4',): 72, ('cat1','cat2'): 710,('cat1','cat3'): 891,('cat1','cat3','cat4') : 621}
    
    import matplotlib.pyplot as plt
    import numpy as np
    from random import random
    
    colors = dict([(k,(random(),random(),random())) for k in data.keys()])
    print colors
    for i, cat in enumerate(sorted(cats)):
        y = 0
        for key, val in data.items():
            if cat in key:
                plt.bar(i, val, bottom=y, color=colors[key])
                plt.text(i,y,' '.join(key))
                y += val
    plt.xticks(np.arange(len(cats))+0.4, cats )
    plt.show()
    
  3. ==============================

    3.대략 교차 그래프가 평면 그래프가 아니고 4 방향 교차가없는 경우는 일반적으로 불가능합니다. 또한 가장자리 길이에 제한이 있습니다 (영역을 나타내는 무정형의 얼룩을 그리지 않는 한). 그래서 원 그리기를 주장한다면, 이것은 더욱 제한적입니다.

    대략 교차 그래프가 평면 그래프가 아니고 4 방향 교차가없는 경우는 일반적으로 불가능합니다. 또한 가장자리 길이에 제한이 있습니다 (영역을 나타내는 무정형의 얼룩을 그리지 않는 한). 그래서 원 그리기를 주장한다면, 이것은 더욱 제한적입니다.

    아주 단순한 경우, 3 방향 Venn 다이어그램을 그릴 수있는 루틴을 만들 수 있습니다. 그런 다음 3 중 트릿의 "반대쪽"에 다른 원을 "추가"합니다. 위의 경우 1,3,4가 그 세 쌍이고, 2가 홀수 한 자입니다.

    데이터가 위의 조건을 만족하기 때문에 (그래프가 평면이고 매우 복잡하기 때문에) 무정형의 얼룩을 사용하면 평면 그래프를 그릴 수 있고 각 가장자리를 서서히 성장시켜 타원체로 풍선을 올릴 수 있습니다 . 당신은 relaxative 방식으로 이것을 할 수 있습니다 : 교차점이 정상보다 낮 으면 풍선 도움말을, 교차점이 있어야하는 것보다 높으면 축소하십시오. (실제로는 뚱뚱한 부분과 늘리는 부분을 2 차원으로하고, 적절히 골라 내십시오. 연장하면 그래프의 나머지 부분이 밀려 나오므로, 이것이 불가능한 일이 아닌지 확인해야합니다. 예를 들어 물리적 인 스프링 기반 레이아웃). 결국 궁극적으로 당신은 정확성을 확인해야 할 대답에 수렴 할 것입니다.

  4. ==============================

    4.가우 덴 (Gauden)의 답변에 대한 변형은 어떻습니까? 각 카테고리는 노드이고, 노드들 사이의 가중 된 에지는 차수 오버랩을 나타낸다. 오버랩이 많을수록 가장자리가 두껍습니다.

    가우 덴 (Gauden)의 답변에 대한 변형은 어떻습니까? 각 카테고리는 노드이고, 노드들 사이의 가중 된 에지는 차수 오버랩을 나타낸다. 오버랩이 많을수록 가장자리가 두껍습니다.

  5. ==============================

    5.고차원 다이어그램의 예를 참조하십시오.

    고차원 다이어그램의 예를 참조하십시오.

    그래도 비례 영역에 맞게 조정하는 방법에 대해 알지 못합니다.

    아마도 적절한 순서의 그래프를 가져 와서 그것을 테셀레이션 한 것일 수 있습니다. 그런 다음 각 삼각형에 원하는 영역을 할당하고 압력 확산을 수행하여 꼭지점이 이동하도록 허용하고 각 삼각형에서 동일한 세트에 속한 이웃으로 "누출"하도록 약간의 압력을 허용 할 수 있습니까?

  6. ==============================

    6.https://github.com/icetime/pyinfor/blob/master/venn.py를 시도해 볼 수도 있지만 MatPlotLib에서도 찾을 수 있습니다. https://github.com/icetime/matplotlib/blob/master/lib/ matplotlib / venn.py하지만 그것이 공식적으로 받아 들여지지는 않는다고 생각합니다.

    https://github.com/icetime/pyinfor/blob/master/venn.py를 시도해 볼 수도 있지만 MatPlotLib에서도 찾을 수 있습니다. https://github.com/icetime/matplotlib/blob/master/lib/ matplotlib / venn.py하지만 그것이 공식적으로 받아 들여지지는 않는다고 생각합니다.

  7. from https://stackoverflow.com/questions/10804432/proportional-venn-diagram-for-more-than-3-sets by cc-by-sa and MIT license