10

MongoDBにドキュメントのコレクションがあり、それぞれのリストに1つ以上のカテゴリがあります。map reduceを使用すると、カテゴリのそれぞれの固有の組み合わせを持つドキュメントの数の詳細を取得できます。

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

ここで、合計は、カテゴリの正確な組み合わせであるドキュメントの数です。

私はこのデータを提示するための賢明な方法を探しています。比例した領域を持つベン図は良い考えだと思います。上記の例を使用すると、cat1の面積は523 + 710 + 891 + 621になり、cat1とcat3の重なりの面積は891 + 621になり、cat1、cat3、cat4の重なりの面積は621になります。

誰かが私がこれを実装する方法について何かヒントがありますか?Python(+ Numpy / MatPlotLib)またはMatLabで実行したいのですが。

4

6 に答える 6

10

問題

オブジェクトの複数の相互接続されたカテゴリの数を表す必要があり、ベン図は、些細な量を超えるカテゴリとそれらの重複を表すことはできません。

解決策

各カテゴリとそれらの組み合わせをグラフのノードと見なします。ノードのサイズが各カテゴリのカウントを表し、エッジが関連するカテゴリを接続するようにグラフを描画します。このアプローチの利点は、複数のカテゴリに簡単に対応できることです。これは、接続されたバブルチャートの一種になります。

結果

ネットワークレイアウト

コード

提案されたソリューションは、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を使用していません。それらは説明の目的で与えられているだけです。

于 2012-05-30T10:29:10.773 に答える
6

ninjageckoは正しいと思います。これは、図がn次元であることを気にしない限り、一般に交差点の図として表すことはできません。ただし、カテゴリごとにすべての交差点を示す図がある場合は、2Dで表すことができ、これ自体を1つの図にすることができます。したがって、これはデータを表すためのより適切な方法である可能性があります。説明のために積み上げ棒グラフを作成しました。

ここに画像の説明を入力してください

コード:

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()
于 2012-05-29T21:49:32.123 に答える
4

これは、大まかに交差点のグラフが平面グラフあり、4方向の交差点がない場合を除いて、一般的に不可能です。エッジの長さにも制限があります(領域を表すためにアモルファスブロブを描画する場合を除きます)。したがって、円を描くことを主張する場合、これはさらに制限されます。

非常に単純なケースでは、3方向ベン図を描画するルーチンを作成してから、トリプレットの「反対側」に別の円を「追加」することができます。上記の場合、1,3,4はそのトリプレットであり2、奇数の1つです。

データが上記の条件を満たすために可能であり(何らかの理由でグラフが平面で非常に複雑である)、アモルファスブロブを使用する場合は、平面グラフを描画し、各エッジをゆっくりと成長させて楕円体に「膨らませる」ことができます。 。これはリラックスした方法で行うことができます。交差が本来あるべき値よりも低い場合は膨らみ、交差点が本来あるべきものよりも高い場合は縮小します。(実際には、これを行うための2つの次元があります:肥大化と伸長。必要に応じて選択します。伸長するとグラフの残りの部分がプッシュされるため、物理的なばねベースを使用するなどして、これによって物事が不可能にならないことを確認する必要があります。レイアウト。)最終的には、答えに収束する可能性があり、正確さを確認する必要があります。

于 2012-05-29T18:18:52.627 に答える
2

ゴーデンの答えのバリエーションはどうですか?各カテゴリはノードであり、ノード間の重み付きエッジは次数のオーバーラップを表します。オーバーラップが多いほど、エッジが厚くなります。

于 2012-06-08T01:38:59.260 に答える
1

高次の図の例をいくつか参照してください。

ただし、比例領域のスケーリングをどのように行うかはわかりません。

たぶん、あなたが適切な順序のグラフを取り、それをテッセレートした場合。次に、各三角形に目的の領域を割り当てて、ある種の圧力拡散を実行し、頂点をシフトさせ、各三角形から同じセットに属する隣接する三角形に圧力を「リーク」させることができますか?

于 2012-05-29T18:20:44.940 に答える
1

https://github.com/icetime/pyinfor/blob/master/venn.pyを試してみることもできますが、MatPlotLibでも見つけましたhttps://github.com/icetime/matplotlib/blob/master/lib/ matplotlib / ven.pyですが、正式に受け入れられているとは思いません。

于 2012-05-29T18:40:46.257 に答える