python代码:有向圆环图(关系图、连接图、DAG图)

在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
from matplotlib.patches import FancyArrowPatch
from matplotlib.colors import Normalize, LinearSegmentedColormap
import matplotlib.colors as mcolors

# Load the adjacency matrix and normalize it
matrix = np.loadtxt('abide-aal90/allAdj_nor.txt') / 25
matrix[matrix < 0.3] = 0


# Create a directed graph from the adjacency matrix
G = nx.from_numpy_array(matrix, create_using=nx.DiGraph)
positions = nx.circular_layout(G)

# Create a custom colormap
light_blue = '#9C5FF2'
light_yellow = '#C2C240'
colors = [(0, light_blue), (0.5, light_yellow), (1, light_blue)]
cmap = LinearSegmentedColormap.from_list('custom_cmap', colors)
norm = Normalize(vmin=0, vmax=len(G.nodes()))


# Function to create custom arrows with gradient colors
def plot_arc(u, v, color, ax):
    x0 = -(u[1] - v[1]) / (u[0] * v[1] - u[1] * v[0])
    y0 = (u[0] - v[0]) / (u[0] * v[1] - u[1] * v[0])
    r = np.sqrt(x0 ** 2 + y0 ** 2 - 1)

    thetaLim = [np.arctan2(u[1] - y0, u[0] - x0), np.arctan2(v[1] - y0, v[0] - x0)]

    if u[0] >= 0 and v[0] >= 0:
        theta = np.concatenate([
            np.linspace(np.max(thetaLim), np.pi, 50),
            np.linspace(-np.pi, np.min(thetaLim), 50)
        ])
    else:
        theta = np.linspace(thetaLim[0], thetaLim[1], 100)

    x = r * np.cos(theta) + x0
    y = r * np.sin(theta) + y0
    ax.plot(x, y, color=color, linewidth=1)

    # Add arrowhead at the end of the arc
    arrow = FancyArrowPatch((x[-2], y[-2]), (x[-1], y[-1]),
                            connectionstyle=f"arc3,rad=0",
                            arrowstyle='-|>', mutation_scale=15, color=color, linewidth=1)
    ax.add_patch(arrow)

# Generate a list of colors, ensuring that adjacent nodes have different colors
def get_distinct_colors(G, num_colors):
    cmap = plt.get_cmap('tab20')  # Use a colormap with many distinct colors
    colors = [cmap(i / num_colors) for i in range(num_colors)]
    return colors


# Get distinct colors for nodes
num_nodes = len(G.nodes())
distinct_colors = get_distinct_colors(G, num_nodes)

# Ensure no adjacent nodes have the same color
color_map = {}
for node in G.nodes():
    # Find a color for the node
    for color in distinct_colors:
        if all(color != color_map.get(neighbor) for neighbor in G.neighbors(node)):
            color_map[node] = color
            break

# Plot the graph
fig, ax = plt.subplots(figsize=(10, 10))

# Draw nodes with distinct colors
node_colors = [color_map[node] for node in G.nodes()]
nx.draw_networkx_nodes(G, positions, node_size=400, node_color="none", edgecolors=node_colors, linewidths=2, ax=ax)

# Draw custom edges with gradient colors
for (u, v) in G.edges():
    start = positions[u]
    end = positions[v]
    color = node_colors[u]

    plot_arc(start, end, color, ax)

# Draw labels for nodes outside the circular layout
radius = np.sqrt(np.sum(np.square(list(positions.values())), axis=1)).max()
offset = 0.07 * radius  # Increase the offset value

for node, (x, y) in positions.items():
    angle = np.arctan2(y, x)
    new_x = x + offset * np.cos(angle)
    new_y = y + offset * np.sin(angle)

    # Determine vertical alignment based on node's position relative to center
    va = 'bottom' if y >= 0 else 'top'

    ax.text(new_x, new_y, str(node + 1), fontsize=9, ha='center', va=va, rotation=np.degrees(angle))

# Remove axis and show plot
ax.axis('off')
plt.show()
# plt.savefig('nor.pdf', format='pdf')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值