or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

analysis.mdclustering.mdcommunity.mddata-types.mdgraph-creation.mdgraph-structure.mdindex.mdio-formats.mdlayout.mdsequences.mdvisualization.md

graph-structure.mddocs/

0

# Graph Structure

1

2

Core operations for adding, removing, and modifying vertices and edges, plus basic graph properties and transformations. These fundamental operations enable dynamic graph construction and manipulation.

3

4

## Capabilities

5

6

### Vertex Operations

7

8

Add, remove, and manipulate vertices in the graph with support for attributes and batch operations.

9

10

```python { .api }

11

class Graph:

12

def add_vertex(self, name=None, **attrs):

13

"""

14

Add single vertex to the graph.

15

16

Parameters:

17

- name: str, vertex name (stored as 'name' attribute)

18

- **attrs: keyword arguments for vertex attributes

19

20

Returns:

21

int, index of newly added vertex

22

"""

23

24

def add_vertices(self, n, attrs=None):

25

"""

26

Add multiple vertices to the graph.

27

28

Parameters:

29

- n: int or list, number of vertices or list of names

30

- attrs: dict, attribute dictionaries for new vertices

31

32

Returns:

33

None

34

"""

35

36

def delete_vertices(self, vertices):

37

"""

38

Remove vertices from the graph.

39

40

Parameters:

41

- vertices: int, str, list, or VertexSeq, vertices to remove

42

43

Returns:

44

None

45

46

Note: Adjacent edges are automatically removed

47

"""

48

49

def vcount(self):

50

"""

51

Get number of vertices in graph.

52

53

Returns:

54

int, vertex count

55

"""

56

```

57

58

**Usage Examples:**

59

60

```python

61

import igraph as ig

62

63

# Create empty graph and add vertices

64

g = ig.Graph()

65

66

# Add single vertex

67

v1 = g.add_vertex(name="Alice", age=25, city="NYC")

68

v2 = g.add_vertex(name="Bob", age=30, city="LA")

69

70

# Add multiple vertices

71

g.add_vertices(3, {"name": ["Carol", "Dave", "Eve"]})

72

73

# Add with different attributes per vertex

74

attrs = [

75

{"name": "Frank", "age": 35},

76

{"name": "Grace", "age": 28}

77

]

78

g.add_vertices(2)

79

for i, attr_dict in enumerate(attrs):

80

for key, val in attr_dict.items():

81

g.vs[g.vcount() - 2 + i][key] = val

82

83

print(f"Vertices: {g.vcount()}") # 7

84

85

# Delete vertices

86

g.delete_vertices([0, 2]) # Remove Alice and Carol

87

g.delete_vertices("Dave") # Remove by name (if unique)

88

```

89

90

### Edge Operations

91

92

Add, remove, and manipulate edges between vertices with support for weights and other attributes.

93

94

```python { .api }

95

class Graph:

96

def add_edge(self, source, target, **attrs):

97

"""

98

Add single edge to the graph.

99

100

Parameters:

101

- source: int or str, source vertex ID or name

102

- target: int or str, target vertex ID or name

103

- **attrs: keyword arguments for edge attributes

104

105

Returns:

106

int, index of newly added edge

107

"""

108

109

def add_edges(self, edges, attrs=None):

110

"""

111

Add multiple edges to the graph.

112

113

Parameters:

114

- edges: list of tuples, edge list [(source, target), ...]

115

- attrs: dict or list, edge attributes

116

117

Returns:

118

None

119

"""

120

121

def delete_edges(self, edges):

122

"""

123

Remove edges from the graph.

124

125

Parameters:

126

- edges: int, tuple, list, or EdgeSeq, edges to remove

127

128

Returns:

129

None

130

"""

131

132

def ecount(self):

133

"""

134

Get number of edges in graph.

135

136

Returns:

137

int, edge count

138

"""

139

140

def get_edgelist(self):

141

"""

142

Get list of all edges as (source, target) tuples.

143

144

Returns:

145

list of tuples, edge list

146

"""

147

```

148

149

**Usage Examples:**

150

151

```python

152

# Start with vertices

153

g = ig.Graph()

154

g.add_vertices(4, {"name": ["A", "B", "C", "D"]})

155

156

# Add single edge with attributes

157

g.add_edge("A", "B", weight=1.5, type="friendship")

158

g.add_edge(0, 2, weight=2.0) # By index

159

160

# Add multiple edges

161

edges = [(1, 2), (2, 3), (3, 0)]

162

g.add_edges(edges)

163

164

# Add edges with attributes

165

edge_attrs = {"weight": [1, 2, 3], "type": ["work", "family", "friend"]}

166

g.add_edges([(0, 1), (1, 3), (2, 0)], edge_attrs)

167

168

print(f"Edges: {g.ecount()}") # 6

169

print("Edge list:", g.get_edgelist())

170

171

# Delete edges

172

g.delete_edges([(0, 1)]) # Remove specific edge

173

g.delete_edges([0, 2]) # Remove by edge index

174

```

175

176

### Basic Properties

177

178

Query fundamental graph properties and characteristics.

179

180

```python { .api }

181

class Graph:

182

def is_directed(self):

183

"""

184

Check if graph is directed.

185

186

Returns:

187

bool, True if directed

188

"""

189

190

def is_simple(self):

191

"""

192

Check if graph is simple (no loops or multiple edges).

193

194

Returns:

195

bool, True if simple

196

"""

197

198

def is_connected(self, mode=WEAK):

199

"""

200

Check if graph is connected.

201

202

Parameters:

203

- mode: connectivity type (WEAK, STRONG for directed graphs)

204

205

Returns:

206

bool, True if connected

207

"""

208

209

def has_multiple(self):

210

"""

211

Check if graph has multiple edges.

212

213

Returns:

214

bool, True if multiple edges exist

215

"""

216

217

def is_loop(self, edges=None):

218

"""

219

Check which edges are self-loops.

220

221

Parameters:

222

- edges: list/EdgeSeq, edges to check (None for all)

223

224

Returns:

225

list of bool, True for each loop edge

226

"""

227

228

def density(self, loops=False):

229

"""

230

Calculate graph density.

231

232

Parameters:

233

- loops: bool, whether to consider self-loops

234

235

Returns:

236

float, density (0-1)

237

"""

238

```

239

240

**Usage Examples:**

241

242

```python

243

# Create sample graph

244

g = ig.Graph(edges=[(0,1), (1,2), (2,0)], directed=False)

245

246

# Check properties

247

print(f"Directed: {g.is_directed()}") # False

248

print(f"Simple: {g.is_simple()}") # True

249

print(f"Connected: {g.is_connected()}") # True

250

print(f"Density: {g.density():.3f}") # 1.0 (complete triangle)

251

252

# Add self-loop and multiple edge

253

g.add_edge(0, 0) # Self-loop

254

g.add_edge(0, 1) # Multiple edge

255

256

print(f"Simple: {g.is_simple()}") # False

257

print(f"Has multiple: {g.has_multiple()}") # True

258

print("Loop edges:", g.is_loop()) # [False, False, False, True, False]

259

```

260

261

### Graph Transformations

262

263

Convert between directed and undirected graphs and apply structural transformations.

264

265

```python { .api }

266

class Graph:

267

def as_directed(self, mutual=True):

268

"""

269

Convert to directed graph.

270

271

Parameters:

272

- mutual: bool, create mutual edges for undirected edges

273

274

Returns:

275

Graph, directed version

276

"""

277

278

def as_undirected(self, mode="collapse", combine_edges=None):

279

"""

280

Convert to undirected graph.

281

282

Parameters:

283

- mode: str, how to handle directed edges

284

("collapse", "each", "mutual")

285

- combine_edges: str/dict, how to combine edge attributes

286

("ignore", "sum", "prod", "mean", "min", "max", "first", "last",

287

"random", or dict mapping attributes to functions)

288

289

Returns:

290

Graph, undirected version

291

"""

292

293

def simplify(self, multiple=True, loops=True, combine_edges=None):

294

"""

295

Remove multiple edges and/or loops.

296

297

Parameters:

298

- multiple: bool, remove multiple edges

299

- loops: bool, remove self-loops

300

- combine_edges: str/dict, how to combine attributes of multiple edges

301

302

Returns:

303

Graph, simplified version

304

"""

305

306

def copy(self):

307

"""

308

Create deep copy of the graph.

309

310

Returns:

311

Graph, independent copy

312

"""

313

```

314

315

**Usage Examples:**

316

317

```python

318

# Undirected graph with multiple edges

319

g = ig.Graph([(0,1), (1,2), (2,0), (0,1), (1,1)], directed=False)

320

321

# Convert to directed

322

g_dir = g.as_directed(mutual=True)

323

print(f"Directed edges: {g_dir.ecount()}") # 8 (each undirected becomes 2 directed)

324

325

# Back to undirected with edge combining

326

g_undir = g_dir.as_undirected(mode="collapse",

327

combine_edges={"weight": "sum"})

328

329

# Simplify graph

330

g_simple = g.simplify(multiple=True, loops=True)

331

print(f"Simplified edges: {g_simple.ecount()}") # 3 (removed duplicates and loop)

332

333

# Copy for safe manipulation

334

g_copy = g.copy()

335

g_copy.delete_vertices([0]) # Original g unchanged

336

```

337

338

### Subgraphs and Induced Subgraphs

339

340

Extract portions of graphs based on vertex or edge selections.

341

342

```python { .api }

343

class Graph:

344

def subgraph(self, vertices, implementation="auto"):

345

"""

346

Create induced subgraph from vertex subset.

347

348

Parameters:

349

- vertices: list/VertexSeq, vertices to include in subgraph

350

- implementation: str, algorithm choice ("auto", "copy_and_delete", "create_from_scratch")

351

352

Returns:

353

Graph, induced subgraph

354

"""

355

356

def subgraph_edges(self, edges, delete_vertices=True):

357

"""

358

Create subgraph from edge subset.

359

360

Parameters:

361

- edges: list/EdgeSeq, edges to include

362

- delete_vertices: bool, remove isolated vertices

363

364

Returns:

365

Graph, edge-induced subgraph

366

"""

367

368

def induced_subgraph(self, vertices, implementation="auto"):

369

"""

370

Alias for subgraph() method.

371

372

Parameters:

373

- vertices: vertex selection

374

- implementation: algorithm choice

375

376

Returns:

377

Graph, induced subgraph

378

"""

379

```

380

381

**Usage Examples:**

382

383

```python

384

# Create larger graph

385

g = ig.Graph.Ring(10) # 10-vertex cycle

386

g.vs["name"] = [f"v{i}" for i in range(10)]

387

388

# Induced subgraph from vertices

389

subverts = [0, 1, 2, 5, 6]

390

sg1 = g.subgraph(subverts)

391

print(f"Subgraph vertices: {sg1.vcount()}") # 5

392

print(f"Subgraph edges: {sg1.ecount()}") # 2 (only edges within subset)

393

394

# Subgraph from edges

395

subedges = [0, 1, 4, 5, 8] # Select specific edges

396

sg2 = g.subgraph_edges(subedges)

397

398

# Use vertex selection with names

399

sg3 = g.subgraph(["v0", "v1", "v9"]) # vertices 0, 1, 9

400

```

401

402

### Degree Operations

403

404

Query and analyze vertex degrees and degree-related properties.

405

406

```python { .api }

407

class Graph:

408

def degree(self, vertices=None, mode=ALL, loops=True):

409

"""

410

Get vertex degrees.

411

412

Parameters:

413

- vertices: list/VertexSeq, vertices to query (None for all)

414

- mode: degree type (ALL, IN, OUT for directed graphs)

415

- loops: bool, count self-loops

416

417

Returns:

418

list of int, vertex degrees

419

"""

420

421

def strength(self, vertices=None, mode=ALL, loops=True, weights=None):

422

"""

423

Get vertex strengths (weighted degrees).

424

425

Parameters:

426

- vertices: vertex selection (None for all)

427

- mode: degree type (ALL, IN, OUT)

428

- loops: bool, count self-loops

429

- weights: str/list, edge weights or attribute name

430

431

Returns:

432

list of float, vertex strengths

433

"""

434

435

def maxdegree(self, vertices=None, mode=ALL, loops=True):

436

"""

437

Get maximum degree in graph.

438

439

Parameters:

440

- vertices: vertex selection for max calculation

441

- mode: degree type (ALL, IN, OUT)

442

- loops: bool, count self-loops

443

444

Returns:

445

int, maximum degree

446

"""

447

448

def degree_sequence(self, mode=ALL):

449

"""

450

Get sorted degree sequence.

451

452

Parameters:

453

- mode: degree type (ALL, IN, OUT)

454

455

Returns:

456

list of int, degrees in descending order

457

"""

458

```

459

460

**Usage Examples:**

461

462

```python

463

# Create weighted graph

464

g = ig.Graph([(0,1), (1,2), (2,0), (1,3)], directed=False)

465

g.es["weight"] = [1, 2, 3, 4]

466

467

# Get degrees

468

degrees = g.degree()

469

print("Degrees:", degrees) # [2, 3, 2, 1]

470

471

# Get strengths (weighted degrees)

472

strengths = g.strength(weights="weight")

473

print("Strengths:", strengths) # [4, 7, 5, 4]

474

475

# Maximum degree

476

max_deg = g.maxdegree()

477

print("Max degree:", max_deg) # 3

478

479

# Degree sequence

480

deg_seq = g.degree_sequence()

481

print("Degree sequence:", deg_seq) # [3, 2, 2, 1]

482

483

# For directed graphs

484

g_dir = g.as_directed()

485

in_degrees = g_dir.degree(mode=ig.IN)

486

out_degrees = g_dir.degree(mode=ig.OUT)

487

```