NetworkX の使い方 （Qiita の タグ関係）

次のページを参考にしました。
[[Python]NetworkXでQiitaのタグ関係図を描く](https://qiita.com/inoory/items/088f719f2fd9a2ea4ee5)

私の投稿のタグ関係を作成してみます。

1) 入力データの用意
[ [tag1, tag2], [tag3], ... ]の形式のデータを用意します。

次のデータから変換します。
https://ekzemplaro.org/qiita/qiita_out.json

変換プログラム

```py:pick_tags.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	pick_tags.py
#
#					Apr/17/2019
#
# ------------------------------------------------------------------
import	sys
import	os
import	json
import	fcntl
#
# ------------------------------------------------------------------
def file_to_str_proc(file_in):
	str_out = ""
	try:
		fp_in = open(file_in,encoding='utf-8')
		str_out = fp_in.read()
		fp_in.close()
	except Exception as ee:
		sys.stderr.write("*** error *** file_to_str_proc ***\n")
		sys.stderr.write(str (ee))
#
	return	str_out
# --------------------------------------------------------------------
def file_write_proc(file_name,str_out):
#
	fp_out = open(file_name,mode='w',encoding='utf-8')
	fcntl.lockf(fp_out, fcntl.LOCK_EX)
	fp_out.write(str_out)
	fp_out.close()
#
# ------------------------------------------------------------------
def convert_proc(array_aa):
	array_bb = []
	for unit in array_aa:
		unit_tags = unit["tags"]
		unit_bb = []
		for uu in unit_tags:
			unit_bb.append(uu["name"])
#
		array_bb.append(unit_bb)
#
	return array_bb
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
file_in = sys.argv[1]
file_out = sys.argv[2]
sys.stderr.write(file_in + "\n")
sys.stderr.write(file_out + "\n")
#
if os.path.exists(file_in):
	try:
		json_str = file_to_str_proc(file_in)
	except Exception as ee:
		sys.stderr.write("*** error *** in file_to_str_proc ***\n")
		sys.stderr.write(str(ee) + "\n")
#
	array_aa = json.loads(json_str)
	array_bb = convert_proc(array_aa)
	json_out_str = json.dumps(array_bb)
	file_write_proc(file_out,json_out_str)
else:
	sys.stderr.write("*** error *** %s doesn't exist ***\n" % file_in)
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行方法

```bash
wget https://ekzemplaro.org/qiita/qiita_out.json
./pick_tags.py qiita_out.json tags.json
```

2) データの処理

プログラム

```py:networkx01.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	networkx01.py
#
#					Apr/18/2019
#
# ------------------------------------------------------------------
import	sys
import	os
import	json
#
import collections
import itertools
import networkx as nx
#
import matplotlib.pyplot as plt
# ------------------------------------------------------------------
def file_to_str_proc(file_in):
	str_out = ""
	try:
		fp_in = open(file_in,encoding='utf-8')
		str_out = fp_in.read()
		fp_in.close()
	except Exception as ee:
		sys.stderr.write("*** error *** file_to_str_proc ***\n")
		sys.stderr.write(str (ee))
#
	return	str_out
# ------------------------------------------------------------------
def draw_proc(G):
	edge_colours = ['black' for edge in G.edges()]
	black_edges = [edge for edge in G.edges()]

	plt.figure(figsize=(15,15))
	pos = nx.spring_layout(G,k=0.3)
	node_size = [ d['count']*20 for (n,d) in G.nodes(data=True)]
	nx.draw_networkx_nodes(G, pos, node_color='cyan',alpha=0.6,node_size=node_size)
	nx.draw_networkx_labels(G,pos,font_size=12,font_family='TakaoExMincho')

	edge_width = [ d['weight']*0.2 for (u,v,d) in G.edges(data=True)]
	nx.draw_networkx_edges(G, pos, alpha=0.4, edge_color='C', width=edge_width)

	plt.axis('off')
	plt.show()
# ------------------------------------------------------------------
def get_tag_count_proc(tags_list):
	nnx = 20
	tag_count = collections.Counter(itertools.chain.from_iterable(tags_list)).most_common(nnx)
#
	return tag_count
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
file_in = sys.argv[1]
json_str = file_to_str_proc(file_in)
tags_list = json.loads(json_str)

tag_count = get_tag_count_proc(tags_list)

for tt in tag_count:
	print(tt)
#
G = nx.Graph()
G.add_nodes_from([(tag, {"count":count}) for tag,count in tag_count])
#
for tags in tags_list:
	for node0,node1 in itertools.combinations(tags, 2):
		if not G.has_node(node0) or not G.has_node(node1):
			continue
		if G.has_edge(node0, node1):
			ww = G[node0][node1]['weight']
			G[node0][node1]['weight'] = ww + 1
#
		else:
			G.add_edge(node0, node1, weight=1)
#
for (u,v,d) in G.edges(data=True):
	print(u,v,d)
#
draw_proc(G)
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行方法

```bash
./networkx01.py tags.json
```

実行結果
![matplot03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/4ce80dcb-0797-d223-0116-d697e449e644.png)