如何相对于质心径向填充 matplotlib 文本对象? 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,{'weight': 143.01364809653174}),33,{'weight': 51.394542826823496}),(7,14,{'weight': 389.22142801036125}),(0,25,{'weight': 486.6995764468493}),30,{'weight': 233.1311348728954}),13,{'weight': 730.2831849050106}),(25,{'weight': 87.14652833884263}),{'weight': 195.41994950707715}),(13,{'weight': 131.22242872081216}),(33,{'weight': 113.96755067449318}),(21,35,{'weight': 100.30461510188701}),12,{'weight': 185.51533865658521}),(12,{'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,ax=ax)
    nx.draw_networkx_labels(graph,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? 

enter image description here

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

enter image description here

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

解决方法

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

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)