Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/networkx/drawing/nx_latex.py: 13%

95 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-10-20 07:00 +0000

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""" 

129import numbers 

130import os 

131 

132import networkx as nx 

133 

134__all__ = [ 

135 "to_latex_raw", 

136 "to_latex", 

137 "write_latex", 

138] 

139 

140 

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

142def to_latex_raw( 

143 G, 

144 pos="pos", 

145 tikz_options="", 

146 default_node_options="", 

147 node_options="node_options", 

148 node_label="label", 

149 default_edge_options="", 

150 edge_options="edge_options", 

151 edge_label="label", 

152 edge_label_options="edge_label_options", 

153): 

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

155 

156 This function produces just the code for the tikzpicture 

157 without any enclosing environment. 

158 

159 Parameters 

160 ========== 

161 G : NetworkX graph 

162 The NetworkX graph to be drawn 

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

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

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

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

167 or (angle:radius). 

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

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

170 tikz_options : string 

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

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

173 default_node_options : string 

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

175 node_options : string or dict 

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

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

178 node_label : string or dict 

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

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

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

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

183 default_edge_options : string 

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

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

186 edge_options : string or dict 

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

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

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

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

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

192 edge_label : string or dict 

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

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

195 label is drawn. 

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

197 edge_label_options : string or dict 

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

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

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

201 

202 Returns 

203 ======= 

204 latex_code : string 

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

206 

207 See Also 

208 ======== 

209 to_latex 

210 write_latex 

211 """ 

212 i4 = "\n " 

213 i8 = "\n " 

214 

215 # set up position dict 

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

217 if not isinstance(pos, dict): 

218 pos = nx.get_node_attributes(G, pos) 

219 if not pos: 

220 # circular layout with radius 2 

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

222 for node in G: 

223 if node not in pos: 

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

225 posnode = pos[node] 

226 if not isinstance(posnode, str): 

227 try: 

228 posx, posy = posnode 

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

230 except (TypeError, ValueError): 

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

232 raise nx.NetworkXError(msg) 

233 

234 # set up all the dicts 

235 if not isinstance(node_options, dict): 

236 node_options = nx.get_node_attributes(G, node_options) 

237 if not isinstance(node_label, dict): 

238 node_label = nx.get_node_attributes(G, node_label) 

239 if not isinstance(edge_options, dict): 

240 edge_options = nx.get_edge_attributes(G, edge_options) 

241 if not isinstance(edge_label, dict): 

242 edge_label = nx.get_edge_attributes(G, edge_label) 

243 if not isinstance(edge_label_options, dict): 

244 edge_label_options = nx.get_edge_attributes(G, edge_label_options) 

245 

246 # process default options (add brackets or not) 

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

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

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

250 if default_edge_options == "": 

251 defe = "[" + linestyle + "]" 

252 elif "-" in default_edge_options: 

253 defe = default_edge_options 

254 else: 

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

256 

257 # Construct the string line by line 

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

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

260 # load the nodes 

261 for n in G: 

262 # node options goes inside square brackets 

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

264 # node text goes inside curly brackets {} 

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

266 

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

268 result += ";\n" 

269 

270 # load the edges 

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

272 for edge in G.edges: 

273 u, v = edge[:2] 

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

275 # add loop options for selfloops if not present 

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

277 e_opts = "loop," + e_opts 

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

279 # TODO -- handle bending of multiedges 

280 

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

282 # edge label options goes inside square brackets [] 

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

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

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

286 

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

288 

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

290 return result 

291 

292 

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

294\usepackage{{tikz}} 

295\usepackage{{subcaption}} 

296 

297\begin{{document}} 

298{content} 

299\end{{document}}""" 

300 

301 

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

303{content}{caption}{label} 

304\end{{figure}}""" 

305 

306 

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

308{content}{caption}{label} 

309 \end{{subfigure}}""" 

310 

311 

312def to_latex( 

313 Gbunch, 

314 pos="pos", 

315 tikz_options="", 

316 default_node_options="", 

317 node_options="node_options", 

318 node_label="node_label", 

319 default_edge_options="", 

320 edge_options="edge_options", 

321 edge_label="edge_label", 

322 edge_label_options="edge_label_options", 

323 caption="", 

324 latex_label="", 

325 sub_captions=None, 

326 sub_labels=None, 

327 n_rows=1, 

328 as_document=True, 

329 document_wrapper=_DOC_WRAPPER_TIKZ, 

330 figure_wrapper=_FIG_WRAPPER, 

331 subfigure_wrapper=_SUBFIG_WRAPPER, 

332): 

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

334 

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

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

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

338 within a single figure environment. 

339 

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

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

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

343 or ``\\input`` statements. 

344 

345 Parameters 

346 ========== 

347 Gbunch : NetworkX graph or iterable of NetworkX graphs 

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

349 to be drawn inside subfigures of a single figure. 

350 pos : string or list of strings 

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

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

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

354 or (angle:radius). 

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

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

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

358 tikz_options : string 

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

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

361 default_node_options : string 

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

363 node_options : string or dict 

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

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

366 node_label : string or dict 

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

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

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

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

371 default_edge_options : string 

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

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

374 edge_options : string or dict 

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

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

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

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

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

380 edge_label : string or dict 

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

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

383 label is drawn. 

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

385 edge_label_options : string or dict 

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

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

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

389 caption : string 

390 The caption string for the figure environment 

391 latex_label : string 

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

393 sub_captions : list of strings 

394 The sub_caption string for each subfigure in the figure 

395 sub_latex_labels : list of strings 

396 The latex label for each subfigure in the figure 

397 n_rows : int 

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

399 as_document : bool 

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

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

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

403 environment with a preamble setting up TikZ. 

404 figure_wrapper : formatted text string 

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

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

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

408 subfigure_wrapper : formatted text string 

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

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

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

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

413 

414 Returns 

415 ======= 

416 latex_code : string 

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

418 

419 See Also 

420 ======== 

421 write_latex 

422 to_latex_raw 

423 """ 

424 if hasattr(Gbunch, "adj"): 

425 raw = to_latex_raw( 

426 Gbunch, 

427 pos, 

428 tikz_options, 

429 default_node_options, 

430 node_options, 

431 node_label, 

432 default_edge_options, 

433 edge_options, 

434 edge_label, 

435 edge_label_options, 

436 ) 

437 else: # iterator of graphs 

438 sbf = subfigure_wrapper 

439 size = 1 / n_rows 

440 

441 N = len(Gbunch) 

442 if isinstance(pos, (str, dict)): 

443 pos = [pos] * N 

444 if sub_captions is None: 

445 sub_captions = [""] * N 

446 if sub_labels is None: 

447 sub_labels = [""] * N 

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

449 raise nx.NetworkXError( 

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

451 ) 

452 

453 raw = "" 

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

455 subraw = to_latex_raw( 

456 G, 

457 pos, 

458 tikz_options, 

459 default_node_options, 

460 node_options, 

461 node_label, 

462 default_edge_options, 

463 edge_options, 

464 edge_label, 

465 edge_label_options, 

466 ) 

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

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

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

470 raw += "\n" 

471 

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

473 raw = raw[:-1] 

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

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

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

477 if as_document: 

478 return document_wrapper.format(content=fig) 

479 return fig 

480 

481 

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

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

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

485 

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

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

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

489 

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

491 

492 Parameters 

493 ---------- 

494 Gbunch : NetworkX graph or iterable of NetworkX graphs 

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

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

497 environment within a single figure environment. 

498 path : filename 

499 Filename or file handle to write to 

500 options : dict 

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

502 

503 pos : string or dict or list 

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

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

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

507 or (angle:radius). 

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

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

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

511 tikz_options : string 

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

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

514 default_node_options : string 

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

516 node_options : string or dict 

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

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

519 node_label : string or dict 

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

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

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

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

524 default_edge_options : string 

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

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

527 edge_options : string or dict 

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

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

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

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

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

533 edge_label : string or dict 

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

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

536 label is drawn. 

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

538 edge_label_options : string or dict 

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

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

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

542 caption : string 

543 The caption string for the figure environment 

544 latex_label : string 

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

546 sub_captions : list of strings 

547 The sub_caption string for each subfigure in the figure 

548 sub_latex_labels : list of strings 

549 The latex label for each subfigure in the figure 

550 n_rows : int 

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

552 as_document : bool 

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

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

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

556 environment with a preamble setting up the TikZ syntax. 

557 figure_wrapper : formatted text string 

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

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

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

561 subfigure_wrapper : formatted text string 

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

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

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

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

566 

567 See Also 

568 ======== 

569 to_latex 

570 """ 

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