如何相对于质心径向填充 matplotlib 文本对象? (Python)

How to pad matplotlib text objects radially with respect to a centroid? (Python)

我正在尝试将我的 networkx 标签扩展到我计算的质心的节点半径之外。例如,如果我们围绕集群 {34, 5, 33} 画一个圆圈,我们实际上会在每个节点和质心之间画一条线,然后沿着该向量向其添加 radial_pad 使其更宽一些。我这样做的原因是因为我在我的实际节点中添加了饼图,我无法终生弄清楚如何让 zorder 工作以显示标签(我已经将 zorder 设置为高数字,计算最大 zorder,手动添加文本对象等)。下一个最好的办法是将节点标签移到节点之外。

此刻,几何图形让我有些头疼,在极坐标之间转换并偏移质心而不是在原点。

import matplotliob.pyplot as plt
import pandas as pd
import networkx as nx
import numpy as np 

edge_data = [(9, 24, {'weight': 262.65595290640806}), (34, 5, {'weight': 143.01364809653174}), (34, 33, {'weight': 51.394542826823496}), (7, 14, {'weight': 389.22142801036125}), (0, 25, {'weight': 486.6995764468493}), (0, 30, {'weight': 233.1311348728954}), (0, 13, {'weight': 730.2831849050106}), (25, 30, {'weight': 87.14652833884263}), (25, 13, {'weight': 195.41994950707715}), (13, 30, {'weight': 131.22242872081216}), (33, 5, {'weight': 113.96755067449318}), (21, 35, {'weight': 100.30461510188701}), (21, 12, {'weight': 185.51533865658521}), (12, 35, {'weight': 106.65748950363549})]
graph = nx.Graph(edge_data)
pos = nx.nx_agraph.graphviz_layout(graph,prog="neato")

radial_pad = 1
with plt.style.context("seaborn-white"):
    fig, ax = plt.subplots(figsize=(5,5))
    nx.draw_networkx_nodes(graph, pos, ax=ax, node_size=500, node_color="white", edgecolors="black")
    nx.draw_networkx_edges(graph, pos, ax=ax)
    nx.draw_networkx_labels(graph, pos, ax=ax)
    for community in nx.connected_components(graph):
        centroid = np.stack(pd.Series(pos)[list(community)].map(list)).mean(axis=0)
        ax.scatter(*centroid, c="black")
        for node in community:
            x, y = pos[node]
            # How do I pad them with respect to the centroid? 

这是我正在尝试做的一个非常粗略的例子:

请注意,我并不是要添加颜色,但我认为这只会在视觉上有所帮助。

首先计算从质心到节点的向量:

delta = pos[node] - centroid

然后转换为单位向量:

unit_vector = delta / np.linalg.norm(delta)

最后,计算单位向量方向的偏移量,保存结果,并在新位置绘制标签:

label_pos = dict()
label_pos[node] = pos[node] + 0.05 * unit_vector
...
nx.draw_networkx_labels(graph, label_pos, ax=ax)