如何相对于质心径向填充 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?
这是我正在尝试做的一个非常粗略的例子:
- 红色是我要移动标签的地方
- 蓝色为当前节点标签与质心之间的半径
- 绿色是我们添加的
radius_pad
值,用于增加标签结束位置的半径
请注意,我并不是要添加颜色,但我认为这只会在视觉上有所帮助。
首先计算从质心到节点的向量:
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)
我正在尝试将我的 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?
这是我正在尝试做的一个非常粗略的例子:
- 红色是我要移动标签的地方
- 蓝色为当前节点标签与质心之间的半径
- 绿色是我们添加的
radius_pad
值,用于增加标签结束位置的半径
请注意,我并不是要添加颜色,但我认为这只会在视觉上有所帮助。
首先计算从质心到节点的向量:
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)