or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-algorithms.mdanalysis.mdcentrality.mdcore-classes.mdgenerators.mdindex.mdlayouts.mdshortest-paths.mdtraversal.mdvisualization.md

visualization.mddocs/

0

# Visualization

1

2

Integration with matplotlib and graphviz for creating publication-quality graph visualizations. rustworkx provides comprehensive visualization capabilities with extensive customization options for nodes, edges, labels, and overall graph appearance.

3

4

## Capabilities

5

6

### Matplotlib Integration

7

8

High-quality graph visualization using matplotlib with extensive customization options.

9

10

```python { .api }

11

def mpl_draw(graph, pos = None, with_labels: bool = False, labels = None, node_list = None, node_size: int = 300, node_color = 'red', node_shape: str = 'o', alpha: float = 1.0, cmap = None, vmin = None, vmax = None, ax = None, linewidths = None, edgecolors = None, label = None, style: str = 'solid', width = None, edge_color = 'black', arrows: bool = True, arrowstyle: str = '-|>', arrowsize: int = 10, edge_cmap = None, edge_vmin = None, edge_vmax = None, connectionstyle: str = 'arc3', min_source_margin: int = 0, min_target_margin: int = 0, font_size: int = 12, font_color = 'black', font_weight: str = 'normal', font_family: str = 'sans-serif', bbox = None, horizontalalignment: str = 'center', verticalalignment: str = 'center', transform = None, clip_on: bool = True, node_attrs = None, edge_attrs = None):

12

"""

13

Draw graph using matplotlib with extensive customization options.

14

15

Provides comprehensive control over all visual elements including

16

nodes, edges, labels, colors, and styling.

17

18

Parameters:

19

- graph: Input graph (PyGraph or PyDiGraph)

20

- pos (dict, optional): Node positions {node_id: (x, y)}, auto-generated if None

21

- with_labels (bool): Display node labels

22

- labels (dict, optional): Custom node labels {node_id: label}

23

- node_list (list, optional): Specific nodes to draw

24

- node_size (int or list): Node sizes in points

25

- node_color (color or list): Node colors

26

- node_shape (str): Node shape ('o', 's', '^', etc.)

27

- alpha (float): Node transparency (0-1)

28

- cmap (colormap): Colormap for node colors

29

- vmin, vmax (float): Color scale limits

30

- ax (matplotlib.axes): Axes to draw on

31

- linewidths (float or list): Node border widths

32

- edgecolors (color or list): Node border colors

33

- label (str): Graph label for legend

34

- style (str): Edge line style ('solid', 'dashed', 'dotted')

35

- width (float or list): Edge line widths

36

- edge_color (color or list): Edge colors

37

- arrows (bool): Draw arrows for directed graphs

38

- arrowstyle (str): Arrow style ('-|>', '->', '<->', etc.)

39

- arrowsize (int): Arrow size

40

- edge_cmap (colormap): Colormap for edge colors

41

- edge_vmin, edge_vmax (float): Edge color scale limits

42

- connectionstyle (str): Edge curve style ('arc3')

43

- min_source_margin, min_target_margin (int): Arrow margins

44

- font_size (int): Label font size

45

- font_color (color): Label text color

46

- font_weight (str): Label font weight ('normal', 'bold')

47

- font_family (str): Label font family

48

- bbox (dict): Label bounding box properties

49

- horizontalalignment (str): Label horizontal alignment

50

- verticalalignment (str): Label vertical alignment

51

- transform (matplotlib.transforms): Coordinate transformation

52

- clip_on (bool): Clip drawing to axes bounds

53

- node_attrs (callable): Function to extract node attributes

54

- edge_attrs (callable): Function to extract edge attributes

55

56

Returns:

57

None (displays graph using matplotlib)

58

"""

59

```

60

61

### Graphviz Integration

62

63

Professional graph visualization using Graphviz rendering engines with DOT language support.

64

65

```python { .api }

66

def graphviz_draw(graph, node_attr_fn = None, edge_attr_fn = None, graph_attr = None, filename = None, image_type = None, method: str = 'dot'):

67

"""

68

Draw graph using Graphviz with DOT language attributes.

69

70

Leverages Graphviz's powerful layout engines and styling

71

capabilities for professional-quality graph visualization.

72

73

Parameters:

74

- graph: Input graph (PyGraph or PyDiGraph)

75

- node_attr_fn (callable, optional): Function returning node attributes dict

76

- edge_attr_fn (callable, optional): Function returning edge attributes dict

77

- graph_attr (dict, optional): Global graph attributes

78

- filename (str, optional): Output file path

79

- image_type (str, optional): Output format ('png', 'svg', 'pdf', etc.)

80

- method (str): Graphviz layout engine ('dot', 'neato', 'fdp', 'sfdp', 'circo', 'twopi')

81

82

Returns:

83

Image or None: PIL Image object if no filename specified, None if saved to file

84

"""

85

```

86

87

## Usage Examples

88

89

### Basic Matplotlib Visualization

90

91

```python

92

import rustworkx as rx

93

import matplotlib.pyplot as plt

94

95

# Create sample graph

96

graph = rx.generators.karate_club_graph()

97

98

# Basic visualization with default settings

99

plt.figure(figsize=(10, 8))

100

rx.visualization.mpl_draw(graph, with_labels=True)

101

plt.title("Karate Club Graph")

102

plt.axis('off')

103

plt.show()

104

```

105

106

### Customized Node and Edge Styling

107

108

```python

109

# Create weighted graph

110

weighted_graph = rx.PyGraph()

111

nodes = weighted_graph.add_nodes_from(['Hub', 'A', 'B', 'C', 'D'])

112

edges = [

113

(0, 1, 0.8), # Hub to A: strong

114

(0, 2, 0.3), # Hub to B: weak

115

(0, 3, 0.9), # Hub to C: very strong

116

(0, 4, 0.1), # Hub to D: very weak

117

(1, 2, 0.5), # A to B: medium

118

(2, 3, 0.7), # B to C: strong

119

]

120

weighted_graph.add_edges_from(edges)

121

122

# Custom layout

123

pos = rx.spring_layout(weighted_graph, seed=42)

124

125

# Customize visualization based on data

126

node_sizes = [1000 if i == 0 else 300 for i in range(5)] # Hub is larger

127

node_colors = ['red' if i == 0 else 'lightblue' for i in range(5)]

128

129

# Edge widths based on weights

130

edge_weights = [weighted_graph.get_edge_data(s, t) for s, t in weighted_graph.edge_list()]

131

edge_widths = [w * 5 for w in edge_weights] # Scale for visibility

132

133

plt.figure(figsize=(10, 8))

134

rx.visualization.mpl_draw(

135

weighted_graph,

136

pos=pos,

137

node_size=node_sizes,

138

node_color=node_colors,

139

width=edge_widths,

140

with_labels=True,

141

labels={0: 'HUB', 1: 'A', 2: 'B', 3: 'C', 4: 'D'},

142

font_size=16,

143

font_weight='bold'

144

)

145

plt.title("Weighted Network with Custom Styling")

146

plt.axis('off')

147

plt.show()

148

```

149

150

### Directed Graph Visualization

151

152

```python

153

# Create directed graph

154

digraph = rx.PyDiGraph()

155

process_nodes = digraph.add_nodes_from(['Start', 'Process1', 'Process2', 'Decision', 'End'])

156

process_edges = [

157

(0, 1, 'begin'),

158

(1, 2, 'data'),

159

(2, 3, 'evaluate'),

160

(3, 4, 'success'),

161

(3, 1, 'retry') # Feedback loop

162

]

163

digraph.add_edges_from(process_edges)

164

165

# Hierarchical layout

166

pos = rx.shell_layout(

167

digraph,

168

nlist=[[0], [1, 2], [3], [4]], # Arrange in levels

169

scale=2.0

170

)

171

172

# Directed graph styling

173

plt.figure(figsize=(12, 8))

174

rx.visualization.mpl_draw(

175

digraph,

176

pos=pos,

177

with_labels=True,

178

labels={i: label for i, label in enumerate(['Start', 'Process1', 'Process2', 'Decision', 'End'])},

179

node_color=['lightgreen', 'lightblue', 'lightblue', 'orange', 'lightcoral'],

180

node_size=1500,

181

arrows=True,

182

arrowsize=20,

183

arrowstyle='->',

184

edge_color='gray',

185

font_size=10,

186

font_weight='bold'

187

)

188

plt.title("Process Flow Diagram")

189

plt.axis('off')

190

plt.show()

191

```

192

193

### Colormap-Based Visualization

194

195

```python

196

# Graph with numeric node data for colormap

197

network = rx.generators.erdos_renyi_gnp_random_graph(20, 0.3, seed=42)

198

199

# Calculate centrality for coloring

200

centrality = rx.betweenness_centrality(network)

201

centrality_values = [centrality[node] for node in network.node_indices()]

202

203

# Use colormap for nodes

204

plt.figure(figsize=(10, 8))

205

rx.visualization.mpl_draw(

206

network,

207

pos=rx.spring_layout(network, seed=42),

208

node_color=centrality_values,

209

cmap='viridis',

210

node_size=500,

211

with_labels=True,

212

font_size=8,

213

font_color='white'

214

)

215

216

# Add colorbar

217

plt.colorbar(plt.cm.ScalarMappable(cmap='viridis'), label='Betweenness Centrality')

218

plt.title("Network Colored by Betweenness Centrality")

219

plt.axis('off')

220

plt.show()

221

```

222

223

### Multi-Graph Subplot Visualization

224

225

```python

226

# Compare different graph structures

227

graphs = {

228

'Complete': rx.generators.complete_graph(6),

229

'Cycle': rx.generators.cycle_graph(6),

230

'Star': rx.generators.star_graph(6),

231

'Path': rx.generators.path_graph(6)

232

}

233

234

fig, axes = plt.subplots(2, 2, figsize=(12, 12))

235

axes = axes.flatten()

236

237

for i, (name, graph) in enumerate(graphs.items()):

238

pos = rx.circular_layout(graph) if name != 'Star' else rx.spring_layout(graph)

239

240

rx.visualization.mpl_draw(

241

graph,

242

pos=pos,

243

ax=axes[i],

244

node_color='lightblue',

245

node_size=300,

246

with_labels=True

247

)

248

axes[i].set_title(f"{name} Graph ({graph.num_nodes()} nodes, {graph.num_edges()} edges)")

249

axes[i].axis('off')

250

251

plt.tight_layout()

252

plt.show()

253

```

254

255

### Graphviz Visualization

256

257

```python

258

# Professional visualization with Graphviz

259

hierarchical_graph = rx.PyDiGraph()

260

org_nodes = hierarchical_graph.add_nodes_from([

261

'CEO', 'CTO', 'CFO', 'Dev1', 'Dev2', 'Acc1', 'Acc2'

262

])

263

org_edges = [

264

(0, 1, 'reports_to'), # CEO -> CTO

265

(0, 2, 'reports_to'), # CEO -> CFO

266

(1, 3, 'manages'), # CTO -> Dev1

267

(1, 4, 'manages'), # CTO -> Dev2

268

(2, 5, 'manages'), # CFO -> Acc1

269

(2, 6, 'manages'), # CFO -> Acc2

270

]

271

hierarchical_graph.add_edges_from(org_edges)

272

273

# Node styling function

274

def node_attrs(node_data):

275

role = ['CEO', 'CTO', 'CFO', 'Dev1', 'Dev2', 'Acc1', 'Acc2'][node_data]

276

if role == 'CEO':

277

return {'shape': 'box', 'style': 'filled', 'fillcolor': 'gold', 'fontweight': 'bold'}

278

elif role in ['CTO', 'CFO']:

279

return {'shape': 'box', 'style': 'filled', 'fillcolor': 'lightblue'}

280

else:

281

return {'shape': 'ellipse', 'style': 'filled', 'fillcolor': 'lightgreen'}

282

283

# Edge styling function

284

def edge_attrs(edge_data):

285

if edge_data == 'reports_to':

286

return {'color': 'red', 'style': 'bold'}

287

else:

288

return {'color': 'blue'}

289

290

# Generate DOT source

291

dot_source = rx.visualization.graphviz_draw(

292

hierarchical_graph,

293

node_attr_fn=lambda node: node_attrs(node),

294

edge_attr_fn=lambda edge: edge_attrs(edge),

295

graph_attr={'rankdir': 'TB', 'splines': 'ortho'}, # Top-to-bottom, orthogonal edges

296

method='dot' # Hierarchical layout

297

)

298

299

print("Generated DOT source:")

300

print(dot_source)

301

302

# Save to file (requires graphviz installation)

303

# rx.visualization.graphviz_draw(

304

# hierarchical_graph,

305

# node_attr_fn=node_attrs,

306

# edge_attr_fn=edge_attrs,

307

# filename='org_chart.png',

308

# image_type='png',

309

# method='dot'

310

# )

311

```

312

313

### Interactive Matplotlib Features

314

315

```python

316

# Create interactive plot with hover information

317

network = rx.generators.barabasi_albert_graph(30, 2, seed=42)

318

pos = rx.spring_layout(network, seed=42)

319

320

# Calculate node properties for display

321

degrees = {node: network.degree(node) for node in network.node_indices()}

322

max_degree = max(degrees.values())

323

324

# Size nodes by degree

325

node_sizes = [300 + (degrees[node] / max_degree) * 700 for node in network.node_indices()]

326

327

plt.figure(figsize=(12, 10))

328

scatter = plt.scatter(

329

[pos[node][0] for node in network.node_indices()],

330

[pos[node][1] for node in network.node_indices()],

331

s=node_sizes,

332

c=[degrees[node] for node in network.node_indices()],

333

cmap='plasma',

334

alpha=0.7

335

)

336

337

# Draw edges

338

for source, target in network.edge_list():

339

x1, y1 = pos[source]

340

x2, y2 = pos[target]

341

plt.plot([x1, x2], [y1, y2], 'k-', alpha=0.3, linewidth=0.5)

342

343

# Add colorbar and labels

344

plt.colorbar(scatter, label='Node Degree')

345

plt.title("Scale-Free Network (Node size and color = degree)")

346

plt.axis('off')

347

348

# Add node labels for high-degree nodes

349

for node in network.node_indices():

350

if degrees[node] > max_degree * 0.7: # Label high-degree nodes

351

x, y = pos[node]

352

plt.annotate(f'{node}\n(deg={degrees[node]})',

353

(x, y), xytext=(5, 5), textcoords='offset points',

354

fontsize=8, bbox=dict(boxstyle='round,pad=0.3', facecolor='white', alpha=0.8))

355

356

plt.show()

357

```

358

359

### Animated Graph Visualization

360

361

```python

362

import matplotlib.animation as animation

363

364

# Create sequence of graphs showing growth

365

def create_growth_sequence(final_size=20, steps=10):

366

"""Create sequence showing preferential attachment growth."""

367

sequences = []

368

369

for i in range(1, steps + 1):

370

size = max(3, int(final_size * i / steps))

371

graph = rx.generators.barabasi_albert_graph(size, 2, seed=42)

372

sequences.append(graph)

373

374

return sequences

375

376

# Generate growth sequence

377

growth_graphs = create_growth_sequence(20, 10)

378

379

# Create animation

380

fig, ax = plt.subplots(figsize=(10, 8))

381

382

def animate(frame):

383

ax.clear()

384

graph = growth_graphs[frame]

385

pos = rx.spring_layout(graph, seed=42)

386

387

rx.visualization.mpl_draw(

388

graph,

389

pos=pos,

390

ax=ax,

391

node_color='lightblue',

392

node_size=300,

393

with_labels=True,

394

font_size=8

395

)

396

397

ax.set_title(f"Preferential Attachment Growth: {graph.num_nodes()} nodes, {graph.num_edges()} edges")

398

ax.axis('off')

399

400

# Create animation

401

anim = animation.FuncAnimation(fig, animate, frames=len(growth_graphs),

402

interval=800, repeat=True)

403

404

plt.show()

405

406

# Save animation (optional)

407

# anim.save('graph_growth.gif', writer='pillow', fps=1)

408

```

409

410

### Advanced Styling with Custom Functions

411

412

```python

413

def create_styled_visualization(graph, title="Styled Graph"):

414

"""Create a professionally styled graph visualization."""

415

416

# Calculate layout

417

pos = rx.spring_layout(graph, seed=42)

418

419

# Calculate node properties

420

degrees = {node: graph.degree(node) for node in graph.node_indices()}

421

centrality = rx.betweenness_centrality(graph)

422

423

# Style configuration

424

node_sizes = [200 + degrees[node] * 100 for node in graph.node_indices()]

425

node_colors = [centrality[node] for node in graph.node_indices()]

426

427

# Create visualization

428

plt.figure(figsize=(12, 10))

429

430

# Draw edges first (behind nodes)

431

for source, target in graph.edge_list():

432

x1, y1 = pos[source]

433

x2, y2 = pos[target]

434

plt.plot([x1, x2], [y1, y2], 'gray', alpha=0.4, linewidth=1)

435

436

# Draw nodes with custom styling

437

scatter = plt.scatter(

438

[pos[node][0] for node in graph.node_indices()],

439

[pos[node][1] for node in graph.node_indices()],

440

s=node_sizes,

441

c=node_colors,

442

cmap='coolwarm',

443

alpha=0.8,

444

edgecolors='black',

445

linewidths=1

446

)

447

448

# Add labels for important nodes

449

important_nodes = [node for node in graph.node_indices()

450

if centrality[node] > 0.1]

451

452

for node in important_nodes:

453

x, y = pos[node]

454

plt.annotate(f'{node}', (x, y), ha='center', va='center',

455

fontweight='bold', fontsize=10,

456

bbox=dict(boxstyle='circle,pad=0.3', facecolor='white', alpha=0.8))

457

458

# Styling

459

plt.colorbar(scatter, label='Betweenness Centrality', shrink=0.8)

460

plt.title(title, fontsize=16, fontweight='bold', pad=20)

461

plt.axis('off')

462

463

# Add legend

464

legend_elements = [

465

plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='gray',

466

markersize=8, label='Small degree'),

467

plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='gray',

468

markersize=12, label='Large degree')

469

]

470

plt.legend(handles=legend_elements, loc='upper right')

471

472

plt.tight_layout()

473

return plt.gcf()

474

475

# Apply to different graph types

476

test_graphs = [

477

(rx.generators.karate_club_graph(), "Karate Club Network"),

478

(rx.generators.barabasi_albert_graph(30, 2), "Scale-Free Network"),

479

(rx.generators.erdos_renyi_gnp_random_graph(25, 0.15), "Random Network")

480

]

481

482

for graph, title in test_graphs:

483

fig = create_styled_visualization(graph, title)

484

plt.show()

485

```