# 必要なライブラリのインポート
import requests
import json
from IPython.display import Image
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
%matplotlib inline
# cyRESTを使うときに便利なユーティリティー集
import py2cytoscape.util as cy
# cyREST サーバーのIPアドレス(Cytoscapeを実行しているマシンのアドレス)。必ず設定が必要です!
IP = '10.0.1.6'
# cyRESTサーバーの情報。デフォルトのポートは1234
PORT_NUMBER = 1234
# 定数としてベースとなるURLを保存
BASE = 'http://' + IP + ':' + str(PORT_NUMBER) + '/v1/'
#JSONをポストするときに必要
HEADERS = {'Content-Type': 'application/json'}
# 表示されるURLをクリックして動作確認。
print('このリンクをクリックして接続確認: ' + BASE)
このリンクをクリックして接続確認: http://10.0.1.6:1234/v1/
# 現在のセッションを削除して新規のものを始める。(全てのネットワークが失われます!)
requests.delete(BASE + 'session')
# 生成されるネットワークに含まれるノード数
NUM_NODES = 100
#小規模なスケールフリーネットワークを作成
scale_free_graph = nx.scale_free_graph(NUM_NODES)
# ネットワークのアトリビュートとして名前をつける
scale_free_graph.graph['name'] = 'スケールフリーネットワーク (ノード数: ' + str(NUM_NODES) + ')'
# ユーティリティーを使ってそれをCytoscape.js 形式のJSONに変換可能なディクショナリオブジェクトを得る
cy_netwiork1 = cy.from_networkx(scale_free_graph)
# CytoscapeにネットワークをPOSTする (Create)
res = requests.post(BASE + 'networks', data=json.dumps(cy_netwiork1), headers=HEADERS)
# 生成されたネットワークのSUID (Session-Unique ID)を得る
suid = res.json()['networkSUID']
# そのSUIDを利用して、自動レイアウトアルゴリズム(ここではばねモデル)を走らせる
requests.get(BASE + 'apply/layouts/force-directed/' + str(suid))
# プリセットのVisual Style (後述)を適用する
requests.get(BASE + 'apply/styles/Directed/' + str(suid))
# 画像APIを利用して、可視化結果をこのノートに埋め込む
sfn_image_url = BASE+'networks/' + str(suid) + '/views/first.png'
print('画像はブラウザでも閲覧できます: ' + sfn_image_url + '?h=1000')
Image(url=sfn_image_url, embed=True)
画像はブラウザでも閲覧できます: http://10.0.1.6:1234/v1/networks/174312/views/first.png?h=1000
ちなみに同じものをNetworkXでそのまま可視化すると以下のようになります
plt.figure(figsize=(12,8));
nx.draw_spring(scale_free_graph)
ネットワークを可視化する詳細は
# まずこの先よく使う可視化の基本コマンドを関数化する
def create_network(network, layout='force-directed', style='Directed'):
res = requests.post(BASE + 'networks', data=json.dumps(network), headers=HEADERS)
suid = res.json()['networkSUID']
requests.get(BASE + 'apply/layouts/' + layout + '/' + str(suid))
requests.get(BASE + 'apply/styles/' + style + '/' + str(suid))
result = {
'suid': suid,
'image_url': BASE + 'networks/' + str(suid) + '/views/first.png'
}
return result
# ネットワークに関する各種指標を計算する
g = nx.powerlaw_cluster_graph(NUM_NODES, 2, 0.8)
# ノードに関する指標
bc = nx.betweenness_centrality(g)
degree = nx.degree(g)
cc = nx.closeness_centrality(g)
nx.set_node_attributes(g, 'betweenness', bc)
nx.set_node_attributes(g, 'closeness', cc)
nx.set_node_attributes(g, 'degree', degree)
# ネットワーク全体に関する指標
g.graph['avg_shortestpath_len'] = nx.average_shortest_path_length(g)
g.graph['density'] = nx.density(g)
cy1 = cy.from_networkx(g)
res = create_network(cy1)
print(res['image_url'])
new_suid = res['suid']
Image(url=res['image_url'], embed=True)
http://10.0.1.6:1234/v1/networks/174908/views/first.png
defaults = [
{
'visualProperty':'NODE_FILL_COLOR',
'value': '#FFFFFF'
},
{
'visualProperty':'NODE_BORDER_WIDTH',
'value': 0
},
{
'visualProperty':'NODE_LABEL_FONT_SIZE',
'value': 18
},
{
'visualProperty':'NODE_LABEL_COLOR',
'value': '#555555'
},
{
'visualProperty':'NODE_SIZE',
'value': 30
},
{
'visualProperty': 'EDGE_WIDTH',
'value': 1
},
{
'visualProperty': 'NODE_TRANSPARENCY',
'value': 200
},
{
'visualProperty': 'EDGE_TRANSPARENCY',
'value': 80
}
]
res = requests.put(BASE + 'styles/Directed/defaults', data=json.dumps(defaults), headers=HEADERS)
Image(BASE+'networks/' + str(new_suid) + '/views/first.png')
node_size_mapping = {
'mappingType': 'continuous',
'mappingColumn': 'degree',
'mappingColumnType': 'Double',
'visualProperty': 'NODE_SIZE',
'points':[
{
'value': 1,
'lesser': '15',
'equal': '15',
'greater': '15'
},
{
'value': max(degree.values()),
'lesser': '100',
'equal': '100',
'greater': '100'
}
]
}
node_color_mapping = {
'mappingType': 'continuous',
'mappingColumn': 'betweenness',
'mappingColumnType': 'Double',
'visualProperty': 'NODE_FILL_COLOR',
'points':[
{
'value': 0,
'lesser': '#C6E2FF',
'equal': '#C6E2FF',
'greater': '#C6E2FF'
},
{
'value': max(bc.values()),
'lesser': '#009ACD',
'equal': '#009ACD',
'greater': '#009ACD'
}
]
}
res = requests.post(BASE + 'styles/Directed/mappings', data=json.dumps([node_size_mapping, node_color_mapping]), headers=HEADERS)
image_url = BASE+'networks/' + str(new_suid) + '/views/first.png'
print(image_url + '?h=1000')
Image(BASE+'networks/' + str(new_suid) + '/views/first.png')
http://10.0.1.6:1234/v1/networks/174908/views/first.png?h=1000