92753


### 前提

3次元のグラフを作成しました。テキストファイルのトポロジー情報を読み込み3次元のグラフをmatplotlibによって出力するといったものです。

### 実現したいこと

本プログラムのリンクをグラデーションを加えてみたいと考えています。

### 該当のソースコード

本ソースコードは前提の項で述べた3次元のグラフを出力するものですが、`cmap='ocean'`を追加しています

[code]

    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    import networkx as nx
    import numpy as np
    import tkinter.filedialog as fd
    
    path = fd.askopenfilename()
    
    # 3.2_トポロジー情報(.txt)の読み込み
    with open(path, "r") as tf:
        line = tf.read().split()
    ran = int(len(line) / 2)
    
    # 3.3_エッジのリストを読み込む
    G = nx.read_edgelist(path,nodetype=int)
    edge_size = nx.number_of_edges(G) # リンク数
    node_size = nx.number_of_nodes(G) # ノード数
    
    # spring_layout アルゴリズムで、3次元の座標を生成する
    pos = nx.spring_layout(G, dim=3)
    # 辞書型から配列型に変換
    pos_ary = np.array([pos[n] for n in G])
    
    # ここから可視化
    fig = plt.figure()
    ax = Axes3D(fig)
    
    # 各ノードの位置に点を打つ
    ax.scatter(
        pos_ary[:, 0],
        pos_ary[:, 1],
        pos_ary[:, 2],
        s=200,
    )
    
    # ノードにラベルを表示する
    for n in G.nodes:
        ax.text(*pos[n], n)
    
    # エッジの表示
    for e in G.edges:
        node0_pos = pos[e[0]]
        node1_pos = pos[e[1]]
        xx = [node0_pos[0], node1_pos[0]]
        yy = [node0_pos[1], node1_pos[1]]
        zz = [node0_pos[2], node1_pos[2]]
        ax.plot(xx, yy, zz, cmap='ocean')
    
    # 出来上がった図を表示
    plt.show()
    
[/code]

以下は読み込むべきテキストファイル(トポロジー情報)です。

[code]

    1 10
    1 11
    1 14
    1 20
    2 9
    2 12
    2 13
    2 15
    2 16
    3 10
    3 11
    3 20
    4 5
    4 8
    4 9
    5 4
    5 9
    6 7
    6 14
    7 6
    7 18
    8 4
    8 11
    8 14
    8 19
    9 2
    9 4
    9 5
    10 1
    10 3
    11 1
    11 3
    11 8
    11 13
    12 2
    12 16
    13 2
    13 11
    14 1
    14 6
    14 8
    15 2
    15 17
    15 21
    16 2
    16 12
    17 15
    18 7
    18 21
    19 8
    19 20
    20 1
    20 3
    20 19
    20 21
    21 15
    21 18
    21 20
    
[/code]

エラー文は以下の通りです。

[code]

    Traceback (most recent call last):
      File "C:/Program Files/Python36/質問用.py", line 47, in <module>
        ax.plot(xx, yy, zz, cmap='ocean')
      File "C:\Users\████\AppData\Roaming\Python\Python36\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 1471, in plot
        lines = super().plot(xs, ys, *args, **kwargs)
      File "C:\Users\████\AppData\Roaming\Python\Python36\site-packages\matplotlib\axes\_axes.py", line 1743, in plot
        lines = [*self._get_lines(*args, data=data, **kwargs)]
      File "C:\Users\████\AppData\Roaming\Python\Python36\site-packages\matplotlib\axes\_base.py", line 273, in __call__
        yield from self._plot_args(this, kwargs)
      File "C:\Users\████\AppData\Roaming\Python\Python36\site-packages\matplotlib\axes\_base.py", line 419, in _plot_args
        for j in range(max(ncx, ncy))]
      File "C:\Users\████\AppData\Roaming\Python\Python36\site-packages\matplotlib\axes\_base.py", line 419, in <listcomp>
        for j in range(max(ncx, ncy))]
      File "C:\Users\████\AppData\Roaming\Python\Python36\site-packages\matplotlib\axes\_base.py", line 312, in _makeline
        seg = mlines.Line2D(x, y, **kw)
      File "C:\Users\████\AppData\Roaming\Python\Python36\site-packages\matplotlib\lines.py", line 390, in __init__
        self.update(kwargs)
      File "C:\Users\████\AppData\Roaming\Python\Python36\site-packages\matplotlib\artist.py", line 996, in update
        raise AttributeError(f"{type(self).__name__!r} object "
    AttributeError: 'Line2D' object has no property 'cmap'
    
[/code]


CC BY-SA 4.0
2022-11-29T02:19:48.817
92487
2022-12-13T13:37:05.393
2022-11-30T04:20:48.810
55268
55268
question
python python3 matplotlib networkx
Networkxのリンクをグラデーションに染めたい


実現したいことは「29個の辺の色を順番に少しずつ変えていく」と解釈して記述例を示します。  
なお，実行環境は「 macOS13(M1), Python 3.10.8, matplotlib 3.6.2 」ですが，この matplotlib は
`ax = Axes3D(fig)` では描画できなかったので変更しています。また，辺と色の対応がわかりやすいように凡例も付加しました。

[code]

    import matplotlib.pyplot as plt
    # from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import cm  # added
    
    # ...
    
    # ax = Axes3D(fig)
    ax = fig.add_subplot(projection='3d')
    
    # ...
    
    for i, e in enumerate(G.edges):
        node0_pos = pos[e[0]]
        node1_pos = pos[e[1]]
        xx = [node0_pos[0], node1_pos[0]]
        yy = [node0_pos[1], node1_pos[1]]
        zz = [node0_pos[2], node1_pos[2]]
        ax.plot(xx, yy, zz, linewidth=5,
                color=cm.ocean(i/(edge_size-1)),
                label=f'{e[0]:2d} - {e[1]:2d}')
    
    hndls, lbls = ax.get_legend_handles_labels()
    ax.legend(handles=hndls, labels=lbls,
              loc='center left',
              bbox_to_anchor=(1.1, 0.5),
              fontsize=6)
    
    plt.show()
    
[/code]


CC BY-SA 4.0
2022-12-13T13:37:05.393
92753
2022-12-13T13:37:05.393
54588
92487
answer