#!/usr/bin/env python # coding: utf-8 # ## 基本セットアップ # # In[7]: # 必要なライブラリのインポート import requests import json from IPython.display import Image import pandas as pd import networkx as nx import matplotlib.pyplot as plt get_ipython().run_line_magic('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) # ここでちゃんとサーバーからレスポンスが返って来れば接続成功です。 # # ## ネットワークデータの生成 # サンプルとして、NetworkXの[グラフジェネレータ](http://networkx.github.io/documentation/networkx-1.9.1/reference/generated/networkx.generators.directed.scale_free_graph.html#networkx.generators.directed.scale_free_graph)を使い、ネットワークを作成。それをCytoscape側で可視化してみます。 # In[8]: # 現在のセッションを削除して新規のものを始める。(全てのネットワークが失われます!) 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) # ちなみに同じものをNetworkXでそのまま可視化すると以下のようになります # In[9]: plt.figure(figsize=(12,8)); nx.draw_spring(scale_free_graph) # ## NetworkXでの解析結果を可視化する # ネットワークを可視化する詳細は # In[10]: # まずこの先よく使う可視化の基本コマンドを関数化する 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) # In[11]: 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') # In[12]: 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')