[Python] Dessinez un diagramme de relation de balises Qiita avec NetworkX

introduction

Je vais vous expliquer comment utiliser la bibliothèque Python NetworkX en utilisant la création d'un graphe de relations de balises attachées aux articles Qiita comme exemple. NetworkX vous permet de dessiner un graphique des nœuds et des arêtes, comme indiqué ci-dessous. sample.png

Environnement d'exécution

Acquisition des données originales

Qiita publie une API pour récupérer les publications, afin que vous puissiez facilement récupérer les publications. Convertissez les données renvoyées au format JSON en un dictionnaire Python avec le code suivant. En cas de non-authentification, il y a une limite de 100 articles par demande et 60 fois par heure. Cette fois, nous ciblerons 100 * 60 = 6000 articles.

import requests
import json

items = []
params = {"page":1, "per_page":100}
for i in range(60):
    print("fetching... page " + str(i+1))
    params["page"] = i + 1
    res = requests.get("https://qiita.com/api/v2/items", params=params)
    items.extend(json.loads(res.text))

Préparation des données

Pour les données acquises par l'API, seules les balises sont extraites et converties au format «[[tag1, tag2], [tag3], ...]».

tags_list = []
for item in items:
    tags = [tag["name"] for tag in item["tags"]]
    tags_list.append(tags)

Utilisez également collections.Counter pour compter le nombre d'occurrences de balises. A ce moment, le tableau multiple est aplati avec ʻitertools.chain.from_iterable (tags_list) `. S'il y a trop de nœuds, la figure sera foirée, alors extrayez les 50 premières balises.

import collections
import itertools

tag_count = collections.Counter(itertools.chain.from_iterable(tags_list)).most_common(50)

Utilisation de NetworkX

De là, nous utiliserons NetworkX pour créer un graphique.

Initialisation et ajout de nœuds

Créez un nouveau graphique avec G = nx.Graph () et ajoutez des nœuds avec des noms de balises. Afin de déterminer la taille du nœud au moment du dessin plus tard, le nombre d'occurrences «count» est mis dans l'attribut du nœud.

import networkx as nx
G = nx.Graph()
G.add_nodes_from([(tag, {"count":count}) for tag,count in tag_count])

Ajouter un bord

Si un article contient plusieurs balises, ajoutez des bords à toutes les combinaisons Par exemple, si vous avez un message marqué avec "Python, networkx, Qiita" comme cet article Créez des bords entre les nœuds Python et les nœuds networkx, entre networkx et Qiita, et entre Qiita et Python. Si l'arête existe déjà, augmentez le «poids» de l'arête.

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):
            G.edge[node0][node1]["weight"] += 1
        else:
            G.add_edge(node0, node1, {"weight":1})

Dessinons un graphique

Trouvons un graphique ici.

%matplotlib inline
import matplotlib.pyplot as plt

plt.figure(figsize=(15,15))
pos = nx.spring_layout(G)
nx.draw_networkx(G,pos)

plt.axis("off")
plt.savefig("default.png ")
plt.show()

default.png

J'ai un graphique que je ne comprends pas.

Ajustement du dessin graphique

À partir de là, nous effectuerons divers ajustements pour rendre le graphique plus propre.

Taille des bords

Supprimez les arêtes qui apparaissent moins fréquemment.

for (u,v,d) in G.edges(data=True):
    if d["weight"] <= 4:
        G.remove_edge(u, v)

Réglage de la force répulsive

Dans pos = nx.spring_layout (G), la position du nœud est déterminée par la force de répulsion entre les nœuds et la force d'attraction due à la taille du "poids" du bord. La force de répulsion entre les nœuds peut être définie en spécifiant l'argument «k», et plus le «k» est grand, plus la disposition des nœuds est proche d'un cercle.

pos = nx.spring_layout(G, k=0.3)

Taille des nœuds et affichage japonais des étiquettes de nœuds

Plus le "compte" est grand, plus la taille du cercle de nœuds est grande. De plus, dans la sortie de la figure précédente, le japonais n'est pas affiché sous forme de carré, définissez donc une police pouvant afficher le japonais.

node_size = [ d["count"]*20 for (n,d) in G.nodes(data=True)]
nx.draw_networkx_nodes(G, pos, node_color="w",alpha=0.6, node_size=node_size)
nx.draw_networkx_labels(G, pos, fontsize=14, font_family="Yu Gothic", font_weight="bold")

Épaisseur du bord

Épaississez le bord en fonction du "poids" du bord.

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)

Cliquez ici pour dessiner

Dessinez avec ce code. Essayez de l'exécuter plusieurs fois ou de modifier les paramètres jusqu'à ce que le graphique obtenu soit correct.

%matplotlib inline
import matplotlib.pyplot as plt
import math

for (u,v,d) in G.edges(data=True):
    if d["weight"] <= 4:
        G.remove_edge(u, v)
    
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='w',alpha=0.6, node_size=node_size)
nx.draw_networkx_labels(G, pos, fontsize=14, font_family="Yu Gothic", font_weight="bold")

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.savefig("g2.png ")
plt.show()

graph2.png Web (Ruby (on Rails), JavaScript, PHP ...) en haut, Python (machine learning) en bas à gauche, iOS lié au milieu, sujets Windows 10 que Bash peut être utilisé en bas à droite ... Comme vous pouvez le voir, nous avons créé un diagramme qui montre les balises populaires et leurs relations.

Recommended Posts

[Python] Dessinez un diagramme de relation de balises Qiita avec NetworkX
Dessinez un graphique avec NetworkX
Dessinez un graphique avec networkx
Dessinez un diagramme CNN en Python
Vous pouvez l'essayer avec une copie! Dessinons un diagramme de réseau sympa avec networkx de Python
Classement des numéros de stock par balise Qiita avec python
[Python] Dessinez un graphe orienté avec Dash Cytoscape
Essayez de dessiner une courbe de vie avec python
[Python] Dessinez un Mickey Mouse avec une tortue [Débutant]
[Python] Comment dessiner un graphique linéaire avec Matplotlib
Dessinez de force quelque chose comme un organigramme avec Python, matplotlib
[Python] Supprimer en spécifiant une balise avec Beautiful Soup
[Python] Comment dessiner un diagramme de dispersion avec Matplotlib
Dessiner un fichier netCDF avec python
Faites une loterie avec Python
Dessinez un cœur en Python
Créer un répertoire avec python
Étudier les mathématiques avec Python: dessiner un graphe sympy (scipy) avec matplotlib
Créons un diagramme PRML avec Python, Numpy et matplotlib.
[Python] Qu'est-ce qu'une instruction with?
Résoudre ABC163 A ~ C avec Python
Faites fonctionner l'imprimante de reçus avec python
Manuel de graphisme Python avec Matplotlib.
Tracez un graphe avec Julia + PyQtGraph (2)
Faisons une interface graphique avec python.
Résoudre ABC166 A ~ D avec Python
Dessinez une matrice de diagramme de dispersion avec python
Dessinez un graphique lâche avec matplotlib
Quine Post avec l'API Qiita (Python)
Créez un environnement virtuel avec Python!
J'ai fait une loterie avec Python.
Dessinez un beau cercle avec numpy
Tracez un graphique avec Julia + PyQtGraph (1)
Créer un environnement virtuel avec Python 3
Dessinez un graphique avec Julia + PyQtGraph (3)
Résoudre ABC168 A ~ C avec Python
Dessinez une illusion d'aquarelle avec détection des contours en Python3 et openCV3
Créer un système de recommandation avec python
Dessinez une courbe Koch avec Python Turtle
[Python] Générer un mot de passe avec Slackbot
Résoudre ABC162 A ~ C avec Python
Obtenez les tendances Qiita avec le scraping Python
Dessinez un graphique avec des pandas + XlsxWriter
Résoudre ABC167 A ~ C avec Python
Résoudre ABC158 A ~ C avec Python
Faisons un graphe avec python! !!
Dessinez une illustration avec Python + OpenCV
Dessinez Riapnov Fractal avec Python, matplotlib
Dessinez un graphique avec l'interface graphique PySimple
[Python] Hériter d'une classe avec des variables de classe
J'ai créé un démon avec Python
Dessinez facilement une carte avec matplotlib.basemap
Ecrire un script batch avec Python3.5 ~
Dessinez une flèche (vecteur) avec opencv / python
J'ai écrit un diagramme de configuration du système avec des diagrammes sur Docker
Comment dessiner une ligne verticale sur une carte de chaleur dessinée avec Python Seaborn
Créez un environnement Python 3 avec pyenv sur Mac et affichez des graphiques Network X
[Pyenv] Construire un environnement python avec ubuntu 16.04
Livre en spirale en Python! Python avec un livre en spirale! (Chapitre 14 ~)
Créer un décorateur de fonction Python avec Class