Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/networkx/drawing/nx_latex.py: 12%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

94 statements  

1r""" 

2***** 

3LaTeX 

4***** 

5 

6Export NetworkX graphs in LaTeX format using the TikZ library within TeX/LaTeX. 

7Usually, you will want the drawing to appear in a figure environment so 

8you use ``to_latex(G, caption="A caption")``. If you want the raw 

9drawing commands without a figure environment use :func:`to_latex_raw`. 

10And if you want to write to a file instead of just returning the latex 

11code as a string, use ``write_latex(G, "filename.tex", caption="A caption")``. 

12 

13To construct a figure with subfigures for each graph to be shown, provide 

14``to_latex`` or ``write_latex`` a list of graphs, a list of subcaptions, 

15and a number of rows of subfigures inside the figure. 

16 

17To be able to refer to the figures or subfigures in latex using ``\\ref``, 

18the keyword ``latex_label`` is available for figures and `sub_labels` for 

19a list of labels, one for each subfigure. 

20 

21We intend to eventually provide an interface to the TikZ Graph 

22features which include e.g. layout algorithms. 

23 

24Let us know via github what you'd like to see available, or better yet 

25give us some code to do it, or even better make a github pull request 

26to add the feature. 

27 

28The TikZ approach 

29================= 

30Drawing options can be stored on the graph as node/edge attributes, or 

31can be provided as dicts keyed by node/edge to a string of the options 

32for that node/edge. Similarly a label can be shown for each node/edge 

33by specifying the labels as graph node/edge attributes or by providing 

34a dict keyed by node/edge to the text to be written for that node/edge. 

35 

36Options for the tikzpicture environment (e.g. "[scale=2]") can be provided 

37via a keyword argument. Similarly default node and edge options can be 

38provided through keywords arguments. The default node options are applied 

39to the single TikZ "path" that draws all nodes (and no edges). The default edge 

40options are applied to a TikZ "scope" which contains a path for each edge. 

41 

42Examples 

43======== 

44>>> G = nx.path_graph(3) 

45>>> nx.write_latex(G, "just_my_figure.tex", as_document=True) 

46>>> nx.write_latex(G, "my_figure.tex", caption="A path graph", latex_label="fig1") 

47>>> latex_code = nx.to_latex(G) # a string rather than a file 

48 

49You can change many features of the nodes and edges. 

50 

51>>> G = nx.path_graph(4, create_using=nx.DiGraph) 

52>>> pos = {n: (n, n) for n in G} # nodes set on a line 

53 

54>>> G.nodes[0]["style"] = "blue" 

55>>> G.nodes[2]["style"] = "line width=3,draw" 

56>>> G.nodes[3]["label"] = "Stop" 

57>>> G.edges[(0, 1)]["label"] = "1st Step" 

58>>> G.edges[(0, 1)]["label_opts"] = "near start" 

59>>> G.edges[(1, 2)]["style"] = "line width=3" 

60>>> G.edges[(1, 2)]["label"] = "2nd Step" 

61>>> G.edges[(2, 3)]["style"] = "green" 

62>>> G.edges[(2, 3)]["label"] = "3rd Step" 

63>>> G.edges[(2, 3)]["label_opts"] = "near end" 

64 

65>>> nx.write_latex(G, "latex_graph.tex", pos=pos, as_document=True) 

66 

67Then compile the LaTeX using something like ``pdflatex latex_graph.tex`` 

68and view the pdf file created: ``latex_graph.pdf``. 

69 

70If you want **subfigures** each containing one graph, you can input a list of graphs. 

71 

72>>> H1 = nx.path_graph(4) 

73>>> H2 = nx.complete_graph(4) 

74>>> H3 = nx.path_graph(8) 

75>>> H4 = nx.complete_graph(8) 

76>>> graphs = [H1, H2, H3, H4] 

77>>> caps = ["Path 4", "Complete graph 4", "Path 8", "Complete graph 8"] 

78>>> lbls = ["fig2a", "fig2b", "fig2c", "fig2d"] 

79>>> nx.write_latex(graphs, "subfigs.tex", n_rows=2, sub_captions=caps, sub_labels=lbls) 

80>>> latex_code = nx.to_latex(graphs, n_rows=2, sub_captions=caps, sub_labels=lbls) 

81 

82>>> node_color = {0: "red", 1: "orange", 2: "blue", 3: "gray!90"} 

83>>> edge_width = {e: "line width=1.5" for e in H3.edges} 

84>>> pos = nx.circular_layout(H3) 

85>>> latex_code = nx.to_latex(H3, pos, node_options=node_color, edge_options=edge_width) 

86>>> print(latex_code) 

87\documentclass{report} 

88\usepackage{tikz} 

89\usepackage{subcaption} 

90<BLANKLINE> 

91\begin{document} 

92\begin{figure} 

93 \begin{tikzpicture} 

94 \draw 

95 (1.0, 0.0) node[red] (0){0} 

96 (0.707, 0.707) node[orange] (1){1} 

97 (-0.0, 1.0) node[blue] (2){2} 

98 (-0.707, 0.707) node[gray!90] (3){3} 

99 (-1.0, -0.0) node (4){4} 

100 (-0.707, -0.707) node (5){5} 

101 (0.0, -1.0) node (6){6} 

102 (0.707, -0.707) node (7){7}; 

103 \begin{scope}[-] 

104 \draw[line width=1.5] (0) to (1); 

105 \draw[line width=1.5] (1) to (2); 

106 \draw[line width=1.5] (2) to (3); 

107 \draw[line width=1.5] (3) to (4); 

108 \draw[line width=1.5] (4) to (5); 

109 \draw[line width=1.5] (5) to (6); 

110 \draw[line width=1.5] (6) to (7); 

111 \end{scope} 

112 \end{tikzpicture} 

113\end{figure} 

114\end{document} 

115 

116Notes 

117----- 

118If you want to change the preamble/postamble of the figure/document/subfigure 

119environment, use the keyword arguments: `figure_wrapper`, `document_wrapper`, 

120`subfigure_wrapper`. The default values are stored in private variables 

121e.g. ``nx.nx_layout._DOCUMENT_WRAPPER`` 

122 

123References 

124---------- 

125TikZ: https://tikz.dev/ 

126 

127TikZ options details: https://tikz.dev/tikz-actions 

128""" 

129 

130import networkx as nx 

131 

132__all__ = [ 

133 "to_latex_raw", 

134 "to_latex", 

135 "write_latex", 

136] 

137 

138 

139@nx.utils.not_implemented_for("multigraph") 

140def to_latex_raw( 

141 G, 

142 pos="pos", 

143 tikz_options="", 

144 default_node_options="", 

145 node_options="node_options", 

146 node_label="label", 

147 default_edge_options="", 

148 edge_options="edge_options", 

149 edge_label="label", 

150 edge_label_options="edge_label_options", 

151): 

152 """Return a string of the LaTeX/TikZ code to draw `G` 

153 

154 This function produces just the code for the tikzpicture 

155 without any enclosing environment. 

156 

157 Parameters 

158 ========== 

159 G : NetworkX graph 

160 The NetworkX graph to be drawn 

161 pos : string or dict (default "pos") 

162 The name of the node attribute on `G` that holds the position of each node. 

163 Positions can be sequences of length 2 with numbers for (x,y) coordinates. 

164 They can also be strings to denote positions in TikZ style, such as (x, y) 

165 or (angle:radius). 

166 If a dict, it should be keyed by node to a position. 

167 If an empty dict, a circular layout is computed by TikZ. 

168 tikz_options : string 

169 The tikzpicture options description defining the options for the picture. 

170 Often large scale options like `[scale=2]`. 

171 default_node_options : string 

172 The draw options for a path of nodes. Individual node options override these. 

173 node_options : string or dict 

174 The name of the node attribute on `G` that holds the options for each node. 

175 Or a dict keyed by node to a string holding the options for that node. 

176 node_label : string or dict 

177 The name of the node attribute on `G` that holds the node label (text) 

178 displayed for each node. If the attribute is "" or not present, the node 

179 itself is drawn as a string. LaTeX processing such as ``"$A_1$"`` is allowed. 

180 Or a dict keyed by node to a string holding the label for that node. 

181 default_edge_options : string 

182 The options for the scope drawing all edges. The default is "[-]" for 

183 undirected graphs and "[->]" for directed graphs. 

184 edge_options : string or dict 

185 The name of the edge attribute on `G` that holds the options for each edge. 

186 If the edge is a self-loop and ``"loop" not in edge_options`` the option 

187 "loop," is added to the options for the self-loop edge. Hence you can 

188 use "[loop above]" explicitly, but the default is "[loop]". 

189 Or a dict keyed by edge to a string holding the options for that edge. 

190 edge_label : string or dict 

191 The name of the edge attribute on `G` that holds the edge label (text) 

192 displayed for each edge. If the attribute is "" or not present, no edge 

193 label is drawn. 

194 Or a dict keyed by edge to a string holding the label for that edge. 

195 edge_label_options : string or dict 

196 The name of the edge attribute on `G` that holds the label options for 

197 each edge. For example, "[sloped,above,blue]". The default is no options. 

198 Or a dict keyed by edge to a string holding the label options for that edge. 

199 

200 Returns 

201 ======= 

202 latex_code : string 

203 The text string which draws the desired graph(s) when compiled by LaTeX. 

204 

205 See Also 

206 ======== 

207 to_latex 

208 write_latex 

209 """ 

210 i4 = "\n " 

211 i8 = "\n " 

212 

213 # set up position dict 

214 # TODO allow pos to be None and use a nice TikZ default 

215 if not isinstance(pos, dict): 

216 pos = nx.get_node_attributes(G, pos) 

217 if not pos: 

218 # circular layout with radius 2 

219 pos = {n: f"({round(360.0 * i / len(G), 3)}:2)" for i, n in enumerate(G)} 

220 for node in G: 

221 if node not in pos: 

222 raise nx.NetworkXError(f"node {node} has no specified pos {pos}") 

223 posnode = pos[node] 

224 if not isinstance(posnode, str): 

225 try: 

226 posx, posy = posnode 

227 pos[node] = f"({round(posx, 3)}, {round(posy, 3)})" 

228 except (TypeError, ValueError): 

229 msg = f"position pos[{node}] is not 2-tuple or a string: {posnode}" 

230 raise nx.NetworkXError(msg) 

231 

232 # set up all the dicts 

233 if not isinstance(node_options, dict): 

234 node_options = nx.get_node_attributes(G, node_options) 

235 if not isinstance(node_label, dict): 

236 node_label = nx.get_node_attributes(G, node_label) 

237 if not isinstance(edge_options, dict): 

238 edge_options = nx.get_edge_attributes(G, edge_options) 

239 if not isinstance(edge_label, dict): 

240 edge_label = nx.get_edge_attributes(G, edge_label) 

241 if not isinstance(edge_label_options, dict): 

242 edge_label_options = nx.get_edge_attributes(G, edge_label_options) 

243 

244 # process default options (add brackets or not) 

245 topts = "" if tikz_options == "" else f"[{tikz_options.strip('[]')}]" 

246 defn = "" if default_node_options == "" else f"[{default_node_options.strip('[]')}]" 

247 linestyle = f"{'->' if G.is_directed() else '-'}" 

248 if default_edge_options == "": 

249 defe = "[" + linestyle + "]" 

250 elif "-" in default_edge_options: 

251 defe = default_edge_options 

252 else: 

253 defe = f"[{linestyle},{default_edge_options.strip('[]')}]" 

254 

255 # Construct the string line by line 

256 result = " \\begin{tikzpicture}" + topts 

257 result += i4 + " \\draw" + defn 

258 # load the nodes 

259 for n in G: 

260 # node options goes inside square brackets 

261 nopts = f"[{node_options[n].strip('[]')}]" if n in node_options else "" 

262 # node text goes inside curly brackets {} 

263 ntext = f"{{{node_label[n]}}}" if n in node_label else f"{{{n}}}" 

264 

265 result += i8 + f"{pos[n]} node{nopts} ({n}){ntext}" 

266 result += ";\n" 

267 

268 # load the edges 

269 result += " \\begin{scope}" + defe 

270 for edge in G.edges: 

271 u, v = edge[:2] 

272 e_opts = f"{edge_options[edge]}".strip("[]") if edge in edge_options else "" 

273 # add loop options for selfloops if not present 

274 if u == v and "loop" not in e_opts: 

275 e_opts = "loop," + e_opts 

276 e_opts = f"[{e_opts}]" if e_opts != "" else "" 

277 # TODO -- handle bending of multiedges 

278 

279 els = edge_label_options[edge] if edge in edge_label_options else "" 

280 # edge label options goes inside square brackets [] 

281 els = f"[{els.strip('[]')}]" 

282 # edge text is drawn using the TikZ node command inside curly brackets {} 

283 e_label = f" node{els} {{{edge_label[edge]}}}" if edge in edge_label else "" 

284 

285 result += i8 + f"\\draw{e_opts} ({u}) to{e_label} ({v});" 

286 

287 result += "\n \\end{scope}\n \\end{tikzpicture}\n" 

288 return result 

289 

290 

291_DOC_WRAPPER_TIKZ = r"""\documentclass{{report}} 

292\usepackage{{tikz}} 

293\usepackage{{subcaption}} 

294 

295\begin{{document}} 

296{content} 

297\end{{document}}""" 

298 

299 

300_FIG_WRAPPER = r"""\begin{{figure}} 

301{content}{caption}{label} 

302\end{{figure}}""" 

303 

304 

305_SUBFIG_WRAPPER = r""" \begin{{subfigure}}{{{size}\textwidth}} 

306{content}{caption}{label} 

307 \end{{subfigure}}""" 

308 

309 

310def to_latex( 

311 Gbunch, 

312 pos="pos", 

313 tikz_options="", 

314 default_node_options="", 

315 node_options="node_options", 

316 node_label="node_label", 

317 default_edge_options="", 

318 edge_options="edge_options", 

319 edge_label="edge_label", 

320 edge_label_options="edge_label_options", 

321 caption="", 

322 latex_label="", 

323 sub_captions=None, 

324 sub_labels=None, 

325 n_rows=1, 

326 as_document=True, 

327 document_wrapper=_DOC_WRAPPER_TIKZ, 

328 figure_wrapper=_FIG_WRAPPER, 

329 subfigure_wrapper=_SUBFIG_WRAPPER, 

330): 

331 """Return latex code to draw the graph(s) in `Gbunch` 

332 

333 The TikZ drawing utility in LaTeX is used to draw the graph(s). 

334 If `Gbunch` is a graph, it is drawn in a figure environment. 

335 If `Gbunch` is an iterable of graphs, each is drawn in a subfigure environment 

336 within a single figure environment. 

337 

338 If `as_document` is True, the figure is wrapped inside a document environment 

339 so that the resulting string is ready to be compiled by LaTeX. Otherwise, 

340 the string is ready for inclusion in a larger tex document using ``\\include`` 

341 or ``\\input`` statements. 

342 

343 Parameters 

344 ========== 

345 Gbunch : NetworkX graph or iterable of NetworkX graphs 

346 The NetworkX graph to be drawn or an iterable of graphs 

347 to be drawn inside subfigures of a single figure. 

348 pos : string or list of strings 

349 The name of the node attribute on `G` that holds the position of each node. 

350 Positions can be sequences of length 2 with numbers for (x,y) coordinates. 

351 They can also be strings to denote positions in TikZ style, such as (x, y) 

352 or (angle:radius). 

353 If a dict, it should be keyed by node to a position. 

354 If an empty dict, a circular layout is computed by TikZ. 

355 If you are drawing many graphs in subfigures, use a list of position dicts. 

356 tikz_options : string 

357 The tikzpicture options description defining the options for the picture. 

358 Often large scale options like `[scale=2]`. 

359 default_node_options : string 

360 The draw options for a path of nodes. Individual node options override these. 

361 node_options : string or dict 

362 The name of the node attribute on `G` that holds the options for each node. 

363 Or a dict keyed by node to a string holding the options for that node. 

364 node_label : string or dict 

365 The name of the node attribute on `G` that holds the node label (text) 

366 displayed for each node. If the attribute is "" or not present, the node 

367 itself is drawn as a string. LaTeX processing such as ``"$A_1$"`` is allowed. 

368 Or a dict keyed by node to a string holding the label for that node. 

369 default_edge_options : string 

370 The options for the scope drawing all edges. The default is "[-]" for 

371 undirected graphs and "[->]" for directed graphs. 

372 edge_options : string or dict 

373 The name of the edge attribute on `G` that holds the options for each edge. 

374 If the edge is a self-loop and ``"loop" not in edge_options`` the option 

375 "loop," is added to the options for the self-loop edge. Hence you can 

376 use "[loop above]" explicitly, but the default is "[loop]". 

377 Or a dict keyed by edge to a string holding the options for that edge. 

378 edge_label : string or dict 

379 The name of the edge attribute on `G` that holds the edge label (text) 

380 displayed for each edge. If the attribute is "" or not present, no edge 

381 label is drawn. 

382 Or a dict keyed by edge to a string holding the label for that edge. 

383 edge_label_options : string or dict 

384 The name of the edge attribute on `G` that holds the label options for 

385 each edge. For example, "[sloped,above,blue]". The default is no options. 

386 Or a dict keyed by edge to a string holding the label options for that edge. 

387 caption : string 

388 The caption string for the figure environment 

389 latex_label : string 

390 The latex label used for the figure for easy referral from the main text 

391 sub_captions : list of strings 

392 The sub_caption string for each subfigure in the figure 

393 sub_latex_labels : list of strings 

394 The latex label for each subfigure in the figure 

395 n_rows : int 

396 The number of rows of subfigures to arrange for multiple graphs 

397 as_document : bool 

398 Whether to wrap the latex code in a document environment for compiling 

399 document_wrapper : formatted text string with variable ``content``. 

400 This text is called to evaluate the content embedded in a document 

401 environment with a preamble setting up TikZ. 

402 figure_wrapper : formatted text string 

403 This text is evaluated with variables ``content``, ``caption`` and ``label``. 

404 It wraps the content and if a caption is provided, adds the latex code for 

405 that caption, and if a label is provided, adds the latex code for a label. 

406 subfigure_wrapper : formatted text string 

407 This text evaluate variables ``size``, ``content``, ``caption`` and ``label``. 

408 It wraps the content and if a caption is provided, adds the latex code for 

409 that caption, and if a label is provided, adds the latex code for a label. 

410 The size is the vertical size of each row of subfigures as a fraction. 

411 

412 Returns 

413 ======= 

414 latex_code : string 

415 The text string which draws the desired graph(s) when compiled by LaTeX. 

416 

417 See Also 

418 ======== 

419 write_latex 

420 to_latex_raw 

421 """ 

422 if hasattr(Gbunch, "adj"): 

423 raw = to_latex_raw( 

424 Gbunch, 

425 pos, 

426 tikz_options, 

427 default_node_options, 

428 node_options, 

429 node_label, 

430 default_edge_options, 

431 edge_options, 

432 edge_label, 

433 edge_label_options, 

434 ) 

435 else: # iterator of graphs 

436 sbf = subfigure_wrapper 

437 size = 1 / n_rows 

438 

439 N = len(Gbunch) 

440 if isinstance(pos, str | dict): 

441 pos = [pos] * N 

442 if sub_captions is None: 

443 sub_captions = [""] * N 

444 if sub_labels is None: 

445 sub_labels = [""] * N 

446 if not (len(Gbunch) == len(pos) == len(sub_captions) == len(sub_labels)): 

447 raise nx.NetworkXError( 

448 "length of Gbunch, sub_captions and sub_figures must agree" 

449 ) 

450 

451 raw = "" 

452 for G, pos, subcap, sublbl in zip(Gbunch, pos, sub_captions, sub_labels): 

453 subraw = to_latex_raw( 

454 G, 

455 pos, 

456 tikz_options, 

457 default_node_options, 

458 node_options, 

459 node_label, 

460 default_edge_options, 

461 edge_options, 

462 edge_label, 

463 edge_label_options, 

464 ) 

465 cap = f" \\caption{{{subcap}}}" if subcap else "" 

466 lbl = f"\\label{{{sublbl}}}" if sublbl else "" 

467 raw += sbf.format(size=size, content=subraw, caption=cap, label=lbl) 

468 raw += "\n" 

469 

470 # put raw latex code into a figure environment and optionally into a document 

471 raw = raw[:-1] 

472 cap = f"\n \\caption{{{caption}}}" if caption else "" 

473 lbl = f"\\label{{{latex_label}}}" if latex_label else "" 

474 fig = figure_wrapper.format(content=raw, caption=cap, label=lbl) 

475 if as_document: 

476 return document_wrapper.format(content=fig) 

477 return fig 

478 

479 

480@nx.utils.open_file(1, mode="w") 

481def write_latex(Gbunch, path, **options): 

482 """Write the latex code to draw the graph(s) onto `path`. 

483 

484 This convenience function creates the latex drawing code as a string 

485 and writes that to a file ready to be compiled when `as_document` is True 

486 or ready to be ``import`` ed or ``include`` ed into your main LaTeX document. 

487 

488 The `path` argument can be a string filename or a file handle to write to. 

489 

490 Parameters 

491 ---------- 

492 Gbunch : NetworkX graph or iterable of NetworkX graphs 

493 If Gbunch is a graph, it is drawn in a figure environment. 

494 If Gbunch is an iterable of graphs, each is drawn in a subfigure 

495 environment within a single figure environment. 

496 path : string or file 

497 Filename or file handle to write to. 

498 Filenames ending in .gz or .bz2 will be compressed. 

499 options : dict 

500 By default, TikZ is used with options: (others are ignored):: 

501 

502 pos : string or dict or list 

503 The name of the node attribute on `G` that holds the position of each node. 

504 Positions can be sequences of length 2 with numbers for (x,y) coordinates. 

505 They can also be strings to denote positions in TikZ style, such as (x, y) 

506 or (angle:radius). 

507 If a dict, it should be keyed by node to a position. 

508 If an empty dict, a circular layout is computed by TikZ. 

509 If you are drawing many graphs in subfigures, use a list of position dicts. 

510 tikz_options : string 

511 The tikzpicture options description defining the options for the picture. 

512 Often large scale options like `[scale=2]`. 

513 default_node_options : string 

514 The draw options for a path of nodes. Individual node options override these. 

515 node_options : string or dict 

516 The name of the node attribute on `G` that holds the options for each node. 

517 Or a dict keyed by node to a string holding the options for that node. 

518 node_label : string or dict 

519 The name of the node attribute on `G` that holds the node label (text) 

520 displayed for each node. If the attribute is "" or not present, the node 

521 itself is drawn as a string. LaTeX processing such as ``"$A_1$"`` is allowed. 

522 Or a dict keyed by node to a string holding the label for that node. 

523 default_edge_options : string 

524 The options for the scope drawing all edges. The default is "[-]" for 

525 undirected graphs and "[->]" for directed graphs. 

526 edge_options : string or dict 

527 The name of the edge attribute on `G` that holds the options for each edge. 

528 If the edge is a self-loop and ``"loop" not in edge_options`` the option 

529 "loop," is added to the options for the self-loop edge. Hence you can 

530 use "[loop above]" explicitly, but the default is "[loop]". 

531 Or a dict keyed by edge to a string holding the options for that edge. 

532 edge_label : string or dict 

533 The name of the edge attribute on `G` that holds the edge label (text) 

534 displayed for each edge. If the attribute is "" or not present, no edge 

535 label is drawn. 

536 Or a dict keyed by edge to a string holding the label for that edge. 

537 edge_label_options : string or dict 

538 The name of the edge attribute on `G` that holds the label options for 

539 each edge. For example, "[sloped,above,blue]". The default is no options. 

540 Or a dict keyed by edge to a string holding the label options for that edge. 

541 caption : string 

542 The caption string for the figure environment 

543 latex_label : string 

544 The latex label used for the figure for easy referral from the main text 

545 sub_captions : list of strings 

546 The sub_caption string for each subfigure in the figure 

547 sub_latex_labels : list of strings 

548 The latex label for each subfigure in the figure 

549 n_rows : int 

550 The number of rows of subfigures to arrange for multiple graphs 

551 as_document : bool 

552 Whether to wrap the latex code in a document environment for compiling 

553 document_wrapper : formatted text string with variable ``content``. 

554 This text is called to evaluate the content embedded in a document 

555 environment with a preamble setting up the TikZ syntax. 

556 figure_wrapper : formatted text string 

557 This text is evaluated with variables ``content``, ``caption`` and ``label``. 

558 It wraps the content and if a caption is provided, adds the latex code for 

559 that caption, and if a label is provided, adds the latex code for a label. 

560 subfigure_wrapper : formatted text string 

561 This text evaluate variables ``size``, ``content``, ``caption`` and ``label``. 

562 It wraps the content and if a caption is provided, adds the latex code for 

563 that caption, and if a label is provided, adds the latex code for a label. 

564 The size is the vertical size of each row of subfigures as a fraction. 

565 

566 See Also 

567 ======== 

568 to_latex 

569 """ 

570 path.write(to_latex(Gbunch, **options))