292 lines
8.5 KiB
Python
292 lines
8.5 KiB
Python
import pytest
|
|
|
|
import networkx as nx
|
|
|
|
|
|
def test_tikz_attributes():
|
|
G = nx.path_graph(4, create_using=nx.DiGraph)
|
|
pos = {n: (n, n) for n in G}
|
|
|
|
G.add_edge(0, 0)
|
|
G.edges[(0, 0)]["label"] = "Loop"
|
|
G.edges[(0, 0)]["label_options"] = "midway"
|
|
|
|
G.nodes[0]["style"] = "blue"
|
|
G.nodes[1]["style"] = "line width=3,draw"
|
|
G.nodes[2]["style"] = "circle,draw,blue!50"
|
|
G.nodes[3]["label"] = "Stop"
|
|
G.edges[(0, 1)]["label"] = "1st Step"
|
|
G.edges[(0, 1)]["label_options"] = "near end"
|
|
G.edges[(2, 3)]["label"] = "3rd Step"
|
|
G.edges[(2, 3)]["label_options"] = "near start"
|
|
G.edges[(2, 3)]["style"] = "bend left,green"
|
|
G.edges[(1, 2)]["label"] = "2nd"
|
|
G.edges[(1, 2)]["label_options"] = "pos=0.5"
|
|
G.edges[(1, 2)]["style"] = ">->,bend right,line width=3,green!90"
|
|
|
|
output_tex = nx.to_latex(
|
|
G,
|
|
pos=pos,
|
|
as_document=False,
|
|
tikz_options="[scale=3]",
|
|
node_options="style",
|
|
edge_options="style",
|
|
node_label="label",
|
|
edge_label="label",
|
|
edge_label_options="label_options",
|
|
)
|
|
expected_tex = r"""\begin{figure}
|
|
\begin{tikzpicture}[scale=3]
|
|
\draw
|
|
(0, 0) node[blue] (0){0}
|
|
(1, 1) node[line width=3,draw] (1){1}
|
|
(2, 2) node[circle,draw,blue!50] (2){2}
|
|
(3, 3) node (3){Stop};
|
|
\begin{scope}[->]
|
|
\draw (0) to node[near end] {1st Step} (1);
|
|
\draw[loop,] (0) to node[midway] {Loop} (0);
|
|
\draw[>->,bend right,line width=3,green!90] (1) to node[pos=0.5] {2nd} (2);
|
|
\draw[bend left,green] (2) to node[near start] {3rd Step} (3);
|
|
\end{scope}
|
|
\end{tikzpicture}
|
|
\end{figure}"""
|
|
|
|
assert output_tex == expected_tex
|
|
# print(output_tex)
|
|
# # Pretty way to assert that A.to_document() == expected_tex
|
|
# content_same = True
|
|
# for aa, bb in zip(expected_tex.split("\n"), output_tex.split("\n")):
|
|
# if aa != bb:
|
|
# content_same = False
|
|
# print(f"-{aa}|\n+{bb}|")
|
|
# assert content_same
|
|
|
|
|
|
def test_basic_multiple_graphs():
|
|
H1 = nx.path_graph(4)
|
|
H2 = nx.complete_graph(4)
|
|
H3 = nx.path_graph(8)
|
|
H4 = nx.complete_graph(8)
|
|
captions = [
|
|
"Path on 4 nodes",
|
|
"Complete graph on 4 nodes",
|
|
"Path on 8 nodes",
|
|
"Complete graph on 8 nodes",
|
|
]
|
|
labels = ["fig2a", "fig2b", "fig2c", "fig2d"]
|
|
latex_code = nx.to_latex(
|
|
[H1, H2, H3, H4],
|
|
n_rows=2,
|
|
sub_captions=captions,
|
|
sub_labels=labels,
|
|
)
|
|
# print(latex_code)
|
|
assert "begin{document}" in latex_code
|
|
assert "begin{figure}" in latex_code
|
|
assert latex_code.count("begin{subfigure}") == 4
|
|
assert latex_code.count("tikzpicture") == 8
|
|
assert latex_code.count("[-]") == 4
|
|
|
|
|
|
def test_basic_tikz():
|
|
expected_tex = r"""\documentclass{report}
|
|
\usepackage{tikz}
|
|
\usepackage{subcaption}
|
|
|
|
\begin{document}
|
|
\begin{figure}
|
|
\begin{subfigure}{0.5\textwidth}
|
|
\begin{tikzpicture}[scale=2]
|
|
\draw[gray!90]
|
|
(0.749, 0.702) node[red!90] (0){0}
|
|
(1.0, -0.014) node[red!90] (1){1}
|
|
(-0.777, -0.705) node (2){2}
|
|
(-0.984, 0.042) node (3){3}
|
|
(-0.028, 0.375) node[cyan!90] (4){4}
|
|
(-0.412, 0.888) node (5){5}
|
|
(0.448, -0.856) node (6){6}
|
|
(0.003, -0.431) node[cyan!90] (7){7};
|
|
\begin{scope}[->,gray!90]
|
|
\draw (0) to (4);
|
|
\draw (0) to (5);
|
|
\draw (0) to (6);
|
|
\draw (0) to (7);
|
|
\draw (1) to (4);
|
|
\draw (1) to (5);
|
|
\draw (1) to (6);
|
|
\draw (1) to (7);
|
|
\draw (2) to (4);
|
|
\draw (2) to (5);
|
|
\draw (2) to (6);
|
|
\draw (2) to (7);
|
|
\draw (3) to (4);
|
|
\draw (3) to (5);
|
|
\draw (3) to (6);
|
|
\draw (3) to (7);
|
|
\end{scope}
|
|
\end{tikzpicture}
|
|
\caption{My tikz number 1 of 2}\label{tikz_1_2}
|
|
\end{subfigure}
|
|
\begin{subfigure}{0.5\textwidth}
|
|
\begin{tikzpicture}[scale=2]
|
|
\draw[gray!90]
|
|
(0.749, 0.702) node[green!90] (0){0}
|
|
(1.0, -0.014) node[green!90] (1){1}
|
|
(-0.777, -0.705) node (2){2}
|
|
(-0.984, 0.042) node (3){3}
|
|
(-0.028, 0.375) node[purple!90] (4){4}
|
|
(-0.412, 0.888) node (5){5}
|
|
(0.448, -0.856) node (6){6}
|
|
(0.003, -0.431) node[purple!90] (7){7};
|
|
\begin{scope}[->,gray!90]
|
|
\draw (0) to (4);
|
|
\draw (0) to (5);
|
|
\draw (0) to (6);
|
|
\draw (0) to (7);
|
|
\draw (1) to (4);
|
|
\draw (1) to (5);
|
|
\draw (1) to (6);
|
|
\draw (1) to (7);
|
|
\draw (2) to (4);
|
|
\draw (2) to (5);
|
|
\draw (2) to (6);
|
|
\draw (2) to (7);
|
|
\draw (3) to (4);
|
|
\draw (3) to (5);
|
|
\draw (3) to (6);
|
|
\draw (3) to (7);
|
|
\end{scope}
|
|
\end{tikzpicture}
|
|
\caption{My tikz number 2 of 2}\label{tikz_2_2}
|
|
\end{subfigure}
|
|
\caption{A graph generated with python and latex.}
|
|
\end{figure}
|
|
\end{document}"""
|
|
|
|
edges = [
|
|
(0, 4),
|
|
(0, 5),
|
|
(0, 6),
|
|
(0, 7),
|
|
(1, 4),
|
|
(1, 5),
|
|
(1, 6),
|
|
(1, 7),
|
|
(2, 4),
|
|
(2, 5),
|
|
(2, 6),
|
|
(2, 7),
|
|
(3, 4),
|
|
(3, 5),
|
|
(3, 6),
|
|
(3, 7),
|
|
]
|
|
G = nx.DiGraph()
|
|
G.add_nodes_from(range(8))
|
|
G.add_edges_from(edges)
|
|
pos = {
|
|
0: (0.7490296171687696, 0.702353520257394),
|
|
1: (1.0, -0.014221357723796535),
|
|
2: (-0.7765783344161441, -0.7054170966808919),
|
|
3: (-0.9842690223417624, 0.04177547602465483),
|
|
4: (-0.02768523817180917, 0.3745724439551441),
|
|
5: (-0.41154855146767433, 0.8880106515525136),
|
|
6: (0.44780153389148264, -0.8561492709269164),
|
|
7: (0.0032499953371383505, -0.43092436645809945),
|
|
}
|
|
|
|
rc_node_color = {0: "red!90", 1: "red!90", 4: "cyan!90", 7: "cyan!90"}
|
|
gp_node_color = {0: "green!90", 1: "green!90", 4: "purple!90", 7: "purple!90"}
|
|
|
|
H = G.copy()
|
|
nx.set_node_attributes(G, rc_node_color, "color")
|
|
nx.set_node_attributes(H, gp_node_color, "color")
|
|
|
|
sub_captions = ["My tikz number 1 of 2", "My tikz number 2 of 2"]
|
|
sub_labels = ["tikz_1_2", "tikz_2_2"]
|
|
|
|
output_tex = nx.to_latex(
|
|
[G, H],
|
|
[pos, pos],
|
|
tikz_options="[scale=2]",
|
|
default_node_options="gray!90",
|
|
default_edge_options="gray!90",
|
|
node_options="color",
|
|
sub_captions=sub_captions,
|
|
sub_labels=sub_labels,
|
|
caption="A graph generated with python and latex.",
|
|
n_rows=2,
|
|
as_document=True,
|
|
)
|
|
|
|
assert output_tex == expected_tex
|
|
# print(output_tex)
|
|
# # Pretty way to assert that A.to_document() == expected_tex
|
|
# content_same = True
|
|
# for aa, bb in zip(expected_tex.split("\n"), output_tex.split("\n")):
|
|
# if aa != bb:
|
|
# content_same = False
|
|
# print(f"-{aa}|\n+{bb}|")
|
|
# assert content_same
|
|
|
|
|
|
def test_exception_pos_single_graph(to_latex=nx.to_latex):
|
|
# smoke test that pos can be a string
|
|
G = nx.path_graph(4)
|
|
to_latex(G, pos="pos")
|
|
|
|
# must include all nodes
|
|
pos = {0: (1, 2), 1: (0, 1), 2: (2, 1)}
|
|
with pytest.raises(nx.NetworkXError):
|
|
to_latex(G, pos)
|
|
|
|
# must have 2 values
|
|
pos[3] = (1, 2, 3)
|
|
with pytest.raises(nx.NetworkXError):
|
|
to_latex(G, pos)
|
|
pos[3] = 2
|
|
with pytest.raises(nx.NetworkXError):
|
|
to_latex(G, pos)
|
|
|
|
# check that passes with 2 values
|
|
pos[3] = (3, 2)
|
|
to_latex(G, pos)
|
|
|
|
|
|
def test_exception_multiple_graphs(to_latex=nx.to_latex):
|
|
G = nx.path_graph(3)
|
|
pos_bad = {0: (1, 2), 1: (0, 1)}
|
|
pos_OK = {0: (1, 2), 1: (0, 1), 2: (2, 1)}
|
|
fourG = [G, G, G, G]
|
|
fourpos = [pos_OK, pos_OK, pos_OK, pos_OK]
|
|
|
|
# input single dict to use for all graphs
|
|
to_latex(fourG, pos_OK)
|
|
with pytest.raises(nx.NetworkXError):
|
|
to_latex(fourG, pos_bad)
|
|
|
|
# input list of dicts to use for all graphs
|
|
to_latex(fourG, fourpos)
|
|
with pytest.raises(nx.NetworkXError):
|
|
to_latex(fourG, [pos_bad, pos_bad, pos_bad, pos_bad])
|
|
|
|
# every pos dict must include all nodes
|
|
with pytest.raises(nx.NetworkXError):
|
|
to_latex(fourG, [pos_OK, pos_OK, pos_bad, pos_OK])
|
|
|
|
# test sub_captions and sub_labels (len must match Gbunch)
|
|
with pytest.raises(nx.NetworkXError):
|
|
to_latex(fourG, fourpos, sub_captions=["hi", "hi"])
|
|
|
|
with pytest.raises(nx.NetworkXError):
|
|
to_latex(fourG, fourpos, sub_labels=["hi", "hi"])
|
|
|
|
# all pass
|
|
to_latex(fourG, fourpos, sub_captions=["hi"] * 4, sub_labels=["lbl"] * 4)
|
|
|
|
|
|
def test_exception_multigraph():
|
|
G = nx.path_graph(4, create_using=nx.MultiGraph)
|
|
G.add_edge(1, 2)
|
|
with pytest.raises(nx.NetworkXNotImplemented):
|
|
nx.to_latex(G)
|