8

R の igraph パ​​ッケージでは、グラフのレイアウトとして緯度/経度の座標を使用してソーシャル ネットワークをプロットするのに苦労しています。

次の簡単な例を想像してみてください: 地理的な場所と接続がわかっている 4 つのノードを持つネットワーク:

df<-data.frame("from" = c("Bob", "Klaus", "Edith", "Liu"), "to"= c("Edith", "Edith", "Bob", "Klaus"))

ここにはノードのメタデータがあり、Bob はニューヨークに、Klaus はベルリンに、Edith はパリに、Liu は北京に住んでいます。

meta <- data.frame("name"=c("Bob", "Klaus", "Edith", "Liu"), "lon"=c(-74.00714, 13.37699, 2.34120, 116.40708),  "lat"=c(40.71455, 52.51607, 48.85693, 39.90469))

g を igraph オブジェクトにします...

g <- graph.data.frame(df, directed=T, vertices=meta)

...そして、レイアウトを経度/緯度座標として定義します

lo <- layout.norm(as.matrix(meta[,2:3]))
plot.igraph(g, layout=lo)

これらの (実際の) 地理座標を使用してこの例を実行すると、位置が互いに相対的であるという意味で「比較的」正確であることがわかります。ただし、このように多くの座標をプロットすると、世界のデカルト マップが「引き伸ばされた」ように見えます。

座標が 100% 正しく、ノード間の接続を確認できるように、ノードを世界地図上に実際にプロットする方法はありますか? ノード間のリンクを分析したいときに後で必要になる可能性のある多くの機能を提供する igraph パ​​ッケージを使い続けたいと思っています。

4

1 に答える 1

7

ソリューションの 1 つの要素は、コメントで提案したように、間違いなくrescale = FALSEパラメーターです。igraph::plot()OPは、なぜこれで空のプロットを取得するのかと尋ねました? これは、プロット領域がまだ[-1; 1]x 軸と y 軸の両方に沿った間隔に制限されているためです。これは のデフォルトですigraph::plot()。したがってxlim = c(-180, 180)ylim = c(-90, 90)パラメータを指定する必要があります。これにより、すでに正しい位置が得られます。しかし、私たちの目的が世界地図を含む図を作成することである場合、igraph プロットを cairo SVG デバイスに書き込むのが最善の方法かもしれません。次に、任意の SVG エディター (たとえば、 Inkscapeは優れたソリューションです) でグラフの背後にマップを配置できるようになり、グラフとラベルを自由にスケーリングおよび編集できます。これを行うために、他のいくつかのigraph.plottingパラメータを設定する必要がありますが、これはすでにプロポーションと美学に関するものです。SVG出力を生成するために使用したコードは次のとおりです。

#!/usr/bin/Rscript

require(igraph)
require(Cairo)

df <- data.frame("from" = c("Bob", "Klaus", "Edith", "Liu"), 
    "to" = c("Edith", "Edith", "Bob", "Klaus"))

meta <- data.frame("name" = c("Bob", "Klaus", "Edith", "Liu"), 
    "lon" = c(-74.00714, 13.37699, 2.34120, 116.40708), 
    "lat" = c(40.71455, 52.51607, 48.85693, 39.90469))

g <- graph.data.frame(df, directed = TRUE, vertices = meta)

lo <- layout.norm(as.matrix(meta[,2:3]))

dpi = 1.0
Cairo(file = 'map-graph.svg', type = "svg", 
    units = "in", 
    width = 4 / dpi, 
    height = 2 / dpi, 
    dpi = dpi)

plot.igraph(g, 
    layout = lo, 
    xlim = c(-180, 180), 
    ylim = c(-90, 90), 
    rescale = FALSE, 
    edge.curved = TRUE, 
    edge.arrow.size = 10 / dpi, 
    edge.arrow.width = 0.5 / dpi, 
    vertex.label.dist = 50 / dpi, 
    vertex.label.degree = 90 / dpi, 
    vertex.size = 200 / dpi, 
    vertex.label.cex = 21 / dpi,
    vertex.frame.color = NA, 
    vertex.label.color = '#FFFF00', 
    edge.color = '#FFFFFF',
    vertex.label.family = 'sans-serif',
    edge.width = 16 / dpi)

dev.off()

igraph によって生成された SVG が問題ないように見えたら、Inkscape で開くことができます。Ctrl+i次に、ピックスマップの場合はマップをインポート ( ) します。または、ベクター グラフィックス (PDF、SVG など) の場合は開きます。マップを手動でスケーリングおよび配置して、SVG のグラフと同じスケールを設定します (つまり、ポイントが適切な場所に来るまで)。比例スケーリングの場合はCtrl、Inkscape で を保持します。この方法の結果は次のとおりです。

ここに画像の説明を入力

(地図画像は、ウィキメディア・コモンズによって非営利目的で一般に公開されています)。

igraph はこのような図を作成できると思いますが、これはこのソフトウェアの主な目的ではないため、限界があります。ある時点で、まさにこのようなことを行うように設計された地理情報システム (GIS) ソフトウェアの使用を検討するかもしれません。私はそれらの経験はありませんが、qgisはおそらく一見の価値があります。

于 2015-06-05T16:50:59.350 に答える