如何用NetworkX实现图的节点置换与90度旋转?
Hey there! Let's break down how to handle node permutation and graph rotations (80°, 90°, 120°) in NetworkX—especially that 90° rotation with an adjacency matrix you mentioned. All of these operations keep your graph's edge/vertex connections intact; we're only modifying where nodes are drawn.
Node Permutation
Node permutation is just swapping or reassigning node positions while preserving the graph's structure. Since NetworkX relies on layout-generated position dictionaries to plot nodes, we can directly manipulate this dictionary:
- Generate an initial layout for your graph (e.g., circular, spring).
- Define a mapping for which nodes should swap positions.
- Create a new position dictionary using this mapping.
Example Code
import networkx as nx import matplotlib.pyplot as plt # Create a sample graph (or load yours from adjacency matrix later) G = nx.complete_graph(3) # Generate initial position layout pos = nx.circular_layout(G) # Define permutation: swap node 0 and 2, keep node 1 in place permute_map = {0: 2, 2: 0, 1: 1} pos_permuted = {node: pos[permute_map[node]] for node in G.nodes()} # Plot original vs permuted plt.figure(figsize=(8,4)) plt.subplot(121) nx.draw(G, pos, with_labels=True, node_color="lightblue") plt.title("Original Layout") plt.subplot(122) nx.draw(G, pos_permuted, with_labels=True, node_color="lightgreen") plt.title("Permuted Nodes") plt.show()
Graph Rotations (80°, 90°, 120°)
Rotating a graph means applying a geometric rotation to all node positions, centered around the graph's center point. We'll use basic linear algebra (rotation matrices) to do this. The core logic works for any angle—just adjust the degree value.
Rotation Function
This reusable function handles rotation (clockwise or counterclockwise) and centers the rotation on the graph's average position:
import numpy as np def rotate_graph(pos, angle_deg, clockwise=True): # Convert degrees to radians angle_rad = np.radians(angle_deg) # Define rotation matrix if clockwise: rot_matrix = np.array([ [np.cos(angle_rad), np.sin(angle_rad)], [-np.sin(angle_rad), np.cos(angle_rad)] ]) else: rot_matrix = np.array([ [np.cos(angle_rad), -np.sin(angle_rad)], [np.sin(angle_rad), np.cos(angle_rad)] ]) # Calculate graph center (average of all node coordinates) coords = np.array(list(pos.values())) center = coords.mean(axis=0) # Shift coordinates to origin, rotate, then shift back to center shifted_coords = coords - center rotated_coords = shifted_coords @ rot_matrix.T new_coords = rotated_coords + center # Return new position dictionary return {node: new_coords[i] for i, node in enumerate(pos.keys())}
Example: 90° Rotation
# Use the same graph and initial position from earlier pos_rot90 = rotate_graph(pos, 90) # Clockwise 90° # Plot original vs rotated plt.figure(figsize=(8,4)) plt.subplot(121) nx.draw(G, pos, with_labels=True, node_color="lightblue") plt.title("Original Layout") plt.subplot(122) nx.draw(G, pos_rot90, with_labels=True, node_color="salmon") plt.title("Rotated 90° Clockwise") plt.show()
For 80° or 120°
Just pass the desired angle to the function:
# 80° clockwise pos_rot80 = rotate_graph(pos, 80) # 120° counterclockwise pos_rot120 = rotate_graph(pos, 120, clockwise=False)
Working with Adjacency Matrices
If you start with an adjacency matrix, first convert it to a NetworkX graph object. From there, the permutation/rotation steps are identical—since the adjacency matrix only defines the graph's structure, positions are still generated via layout algorithms:
# Example adjacency matrix adj_matrix = np.array([ [0, 1, 1], [1, 0, 1], [1, 1, 0] ]) # Convert to NetworkX graph G_from_adj = nx.from_numpy_array(adj_matrix) # Generate layout and apply rotation pos = nx.circular_layout(G_from_adj) pos_rot90 = rotate_graph(pos, 90) # Plot the rotated graph nx.draw(G_from_adj, pos_rot90, with_labels=True, node_color="purple") plt.title("Rotated 90° (From Adjacency Matrix)") plt.show()
Key takeaway: All position-based transformations (permutation, rotation) only modify the plotting coordinates—your graph's underlying structure (edges, adjacency matrix) stays completely unchanged.
内容的提问来源于stack exchange,提问作者eric lardon

