Fixed database typo and removed unnecessary class identifier.
This commit is contained in:
parent
00ad49a143
commit
45fb349a7d
5098 changed files with 952558 additions and 85 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
249
venv/Lib/site-packages/networkx/drawing/tests/test_agraph.py
Normal file
249
venv/Lib/site-packages/networkx/drawing/tests/test_agraph.py
Normal file
|
@ -0,0 +1,249 @@
|
|||
"""Unit tests for PyGraphviz interface."""
|
||||
import os
|
||||
import tempfile
|
||||
import pytest
|
||||
|
||||
pygraphviz = pytest.importorskip("pygraphviz")
|
||||
|
||||
|
||||
from networkx.testing import assert_edges_equal, assert_nodes_equal, assert_graphs_equal
|
||||
|
||||
import networkx as nx
|
||||
|
||||
|
||||
class TestAGraph:
|
||||
def build_graph(self, G):
|
||||
edges = [("A", "B"), ("A", "C"), ("A", "C"), ("B", "C"), ("A", "D")]
|
||||
G.add_edges_from(edges)
|
||||
G.add_node("E")
|
||||
G.graph["metal"] = "bronze"
|
||||
return G
|
||||
|
||||
def assert_equal(self, G1, G2):
|
||||
assert_nodes_equal(G1.nodes(), G2.nodes())
|
||||
assert_edges_equal(G1.edges(), G2.edges())
|
||||
assert G1.graph["metal"] == G2.graph["metal"]
|
||||
|
||||
def agraph_checks(self, G):
|
||||
G = self.build_graph(G)
|
||||
A = nx.nx_agraph.to_agraph(G)
|
||||
H = nx.nx_agraph.from_agraph(A)
|
||||
self.assert_equal(G, H)
|
||||
|
||||
fname = tempfile.mktemp()
|
||||
nx.drawing.nx_agraph.write_dot(H, fname)
|
||||
Hin = nx.nx_agraph.read_dot(fname)
|
||||
os.unlink(fname)
|
||||
self.assert_equal(H, Hin)
|
||||
|
||||
(fd, fname) = tempfile.mkstemp()
|
||||
with open(fname, "w") as fh:
|
||||
nx.drawing.nx_agraph.write_dot(H, fh)
|
||||
|
||||
with open(fname) as fh:
|
||||
Hin = nx.nx_agraph.read_dot(fh)
|
||||
os.unlink(fname)
|
||||
self.assert_equal(H, Hin)
|
||||
|
||||
def test_from_agraph_name(self):
|
||||
G = nx.Graph(name="test")
|
||||
A = nx.nx_agraph.to_agraph(G)
|
||||
H = nx.nx_agraph.from_agraph(A)
|
||||
assert G.name == "test"
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"graph_class", (nx.Graph, nx.DiGraph, nx.MultiGraph, nx.MultiDiGraph)
|
||||
)
|
||||
def test_from_agraph_create_using(self, graph_class):
|
||||
G = nx.path_graph(3)
|
||||
A = nx.nx_agraph.to_agraph(G)
|
||||
H = nx.nx_agraph.from_agraph(A, create_using=graph_class)
|
||||
assert isinstance(H, graph_class)
|
||||
|
||||
def test_from_agraph_named_edges(self):
|
||||
# Create an AGraph from an existing (non-multi) Graph
|
||||
G = nx.Graph()
|
||||
G.add_nodes_from([0, 1])
|
||||
A = nx.nx_agraph.to_agraph(G)
|
||||
# Add edge (+ name, given by key) to the AGraph
|
||||
A.add_edge(0, 1, key="foo")
|
||||
# Verify a.name roundtrips out to 'key' in from_agraph
|
||||
H = nx.nx_agraph.from_agraph(A)
|
||||
assert isinstance(H, nx.Graph)
|
||||
assert ("0", "1", {"key": "foo"}) in H.edges(data=True)
|
||||
|
||||
def test_undirected(self):
|
||||
self.agraph_checks(nx.Graph())
|
||||
|
||||
def test_directed(self):
|
||||
self.agraph_checks(nx.DiGraph())
|
||||
|
||||
def test_multi_undirected(self):
|
||||
self.agraph_checks(nx.MultiGraph())
|
||||
|
||||
def test_multi_directed(self):
|
||||
self.agraph_checks(nx.MultiDiGraph())
|
||||
|
||||
def test_to_agraph_with_nodedata(self):
|
||||
G = nx.Graph()
|
||||
G.add_node(1, color="red")
|
||||
A = nx.nx_agraph.to_agraph(G)
|
||||
assert dict(A.nodes()[0].attr) == {"color": "red"}
|
||||
|
||||
@pytest.mark.parametrize("graph_class", (nx.Graph, nx.MultiGraph))
|
||||
def test_to_agraph_with_edgedata(self, graph_class):
|
||||
G = graph_class()
|
||||
G.add_nodes_from([0, 1])
|
||||
G.add_edge(0, 1, color="yellow")
|
||||
A = nx.nx_agraph.to_agraph(G)
|
||||
assert dict(A.edges()[0].attr) == {"color": "yellow"}
|
||||
|
||||
def test_view_pygraphviz_path(self, tmp_path):
|
||||
G = nx.complete_graph(3)
|
||||
input_path = str(tmp_path / "graph.png")
|
||||
out_path, A = nx.nx_agraph.view_pygraphviz(G, path=input_path, show=False)
|
||||
assert out_path == input_path
|
||||
# Ensure file is not empty
|
||||
with open(input_path, "rb") as fh:
|
||||
data = fh.read()
|
||||
assert len(data) > 0
|
||||
|
||||
def test_view_pygraphviz_file_suffix(self, tmp_path):
|
||||
G = nx.complete_graph(3)
|
||||
path, A = nx.nx_agraph.view_pygraphviz(G, suffix=1, show=False)
|
||||
assert path[-6:] == "_1.png"
|
||||
|
||||
def test_view_pygraphviz(self):
|
||||
G = nx.Graph() # "An empty graph cannot be drawn."
|
||||
pytest.raises(nx.NetworkXException, nx.nx_agraph.view_pygraphviz, G)
|
||||
G = nx.barbell_graph(4, 6)
|
||||
nx.nx_agraph.view_pygraphviz(G, show=False)
|
||||
|
||||
def test_view_pygraphviz_edgelabel(self):
|
||||
G = nx.Graph()
|
||||
G.add_edge(1, 2, weight=7)
|
||||
G.add_edge(2, 3, weight=8)
|
||||
path, A = nx.nx_agraph.view_pygraphviz(G, edgelabel="weight", show=False)
|
||||
for edge in A.edges():
|
||||
assert edge.attr["weight"] in ("7", "8")
|
||||
|
||||
def test_view_pygraphviz_callable_edgelabel(self):
|
||||
G = nx.complete_graph(3)
|
||||
|
||||
def foo_label(data):
|
||||
return "foo"
|
||||
|
||||
path, A = nx.nx_agraph.view_pygraphviz(G, edgelabel=foo_label, show=False)
|
||||
for edge in A.edges():
|
||||
assert edge.attr["label"] == "foo"
|
||||
|
||||
def test_view_pygraphviz_multigraph_edgelabels(self):
|
||||
G = nx.MultiGraph()
|
||||
G.add_edge(0, 1, key=0, name="left_fork")
|
||||
G.add_edge(0, 1, key=1, name="right_fork")
|
||||
path, A = nx.nx_agraph.view_pygraphviz(G, edgelabel="name", show=False)
|
||||
edges = A.edges()
|
||||
assert len(edges) == 2
|
||||
for edge in edges:
|
||||
assert edge.attr["label"].strip() in ("left_fork", "right_fork")
|
||||
|
||||
def test_graph_with_reserved_keywords(self):
|
||||
# test attribute/keyword clash case for #1582
|
||||
# node: n
|
||||
# edges: u,v
|
||||
G = nx.Graph()
|
||||
G = self.build_graph(G)
|
||||
G.nodes["E"]["n"] = "keyword"
|
||||
G.edges[("A", "B")]["u"] = "keyword"
|
||||
G.edges[("A", "B")]["v"] = "keyword"
|
||||
A = nx.nx_agraph.to_agraph(G)
|
||||
|
||||
def test_view_pygraphviz_no_added_attrs_to_input(self):
|
||||
G = nx.complete_graph(2)
|
||||
path, A = nx.nx_agraph.view_pygraphviz(G, show=False)
|
||||
assert G.graph == {}
|
||||
|
||||
@pytest.mark.xfail(reason="known bug in clean_attrs")
|
||||
def test_view_pygraphviz_leaves_input_graph_unmodified(self):
|
||||
G = nx.complete_graph(2)
|
||||
# Add entries to graph dict that to_agraph handles specially
|
||||
G.graph["node"] = {"width": "0.80"}
|
||||
G.graph["edge"] = {"fontsize": "14"}
|
||||
path, A = nx.nx_agraph.view_pygraphviz(G, show=False)
|
||||
assert G.graph == {"node": {"width": "0.80"}, "edge": {"fontsize": "14"}}
|
||||
|
||||
def test_graph_with_AGraph_attrs(self):
|
||||
G = nx.complete_graph(2)
|
||||
# Add entries to graph dict that to_agraph handles specially
|
||||
G.graph["node"] = {"width": "0.80"}
|
||||
G.graph["edge"] = {"fontsize": "14"}
|
||||
path, A = nx.nx_agraph.view_pygraphviz(G, show=False)
|
||||
# Ensure user-specified values are not lost
|
||||
assert dict(A.node_attr)["width"] == "0.80"
|
||||
assert dict(A.edge_attr)["fontsize"] == "14"
|
||||
|
||||
def test_round_trip_empty_graph(self):
|
||||
G = nx.Graph()
|
||||
A = nx.nx_agraph.to_agraph(G)
|
||||
H = nx.nx_agraph.from_agraph(A)
|
||||
# assert_graphs_equal(G, H)
|
||||
AA = nx.nx_agraph.to_agraph(H)
|
||||
HH = nx.nx_agraph.from_agraph(AA)
|
||||
assert_graphs_equal(H, HH)
|
||||
G.graph["graph"] = {}
|
||||
G.graph["node"] = {}
|
||||
G.graph["edge"] = {}
|
||||
assert_graphs_equal(G, HH)
|
||||
|
||||
@pytest.mark.xfail(reason="integer->string node conversion in round trip")
|
||||
def test_round_trip_integer_nodes(self):
|
||||
G = nx.complete_graph(3)
|
||||
A = nx.nx_agraph.to_agraph(G)
|
||||
H = nx.nx_agraph.from_agraph(A)
|
||||
assert_graphs_equal(G, H)
|
||||
|
||||
def test_graphviz_alias(self):
|
||||
G = self.build_graph(nx.Graph())
|
||||
pos_graphviz = nx.nx_agraph.graphviz_layout(G)
|
||||
pos_pygraphviz = nx.nx_agraph.pygraphviz_layout(G)
|
||||
assert pos_graphviz == pos_pygraphviz
|
||||
|
||||
@pytest.mark.parametrize("root", range(5))
|
||||
def test_pygraphviz_layout_root(self, root):
|
||||
# NOTE: test depends on layout prog being deterministic
|
||||
G = nx.complete_graph(5)
|
||||
A = nx.nx_agraph.to_agraph(G)
|
||||
# Get layout with root arg is not None
|
||||
pygv_layout = nx.nx_agraph.pygraphviz_layout(G, prog="circo", root=root)
|
||||
# Equivalent layout directly on AGraph
|
||||
A.layout(args=f"-Groot={root}", prog="circo")
|
||||
# Parse AGraph layout
|
||||
a1_pos = tuple(float(v) for v in dict(A.get_node("1").attr)["pos"].split(","))
|
||||
assert pygv_layout[1] == a1_pos
|
||||
|
||||
def test_2d_layout(self):
|
||||
G = nx.Graph()
|
||||
G = self.build_graph(G)
|
||||
G.graph["dimen"] = 2
|
||||
pos = nx.nx_agraph.pygraphviz_layout(G, prog="neato")
|
||||
pos = list(pos.values())
|
||||
assert len(pos) == 5
|
||||
assert len(pos[0]) == 2
|
||||
|
||||
def test_3d_layout(self):
|
||||
G = nx.Graph()
|
||||
G = self.build_graph(G)
|
||||
G.graph["dimen"] = 3
|
||||
pos = nx.nx_agraph.pygraphviz_layout(G, prog="neato")
|
||||
pos = list(pos.values())
|
||||
assert len(pos) == 5
|
||||
assert len(pos[0]) == 3
|
||||
|
||||
def test_display_pygraphviz_deprecation_warning(self):
|
||||
G = nx.complete_graph(2)
|
||||
path_name, A = nx.nx_agraph.view_pygraphviz(G, show=False)
|
||||
# Monkeypatch default_opener to prevent window opening
|
||||
nx.utils.default_opener = lambda x: None
|
||||
with pytest.warns(DeprecationWarning, match="display_pygraphviz is deprecated"):
|
||||
with open(path_name, "wb") as fh:
|
||||
nx.nx_agraph.display_pygraphviz(A, fh, prog="dot")
|
406
venv/Lib/site-packages/networkx/drawing/tests/test_layout.py
Normal file
406
venv/Lib/site-packages/networkx/drawing/tests/test_layout.py
Normal file
|
@ -0,0 +1,406 @@
|
|||
"""Unit tests for layout functions."""
|
||||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
import pytest
|
||||
|
||||
numpy = pytest.importorskip("numpy")
|
||||
test_smoke_empty_graphscipy = pytest.importorskip("scipy")
|
||||
|
||||
|
||||
class TestLayout:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
cls.Gi = nx.grid_2d_graph(5, 5)
|
||||
cls.Gs = nx.Graph()
|
||||
nx.add_path(cls.Gs, "abcdef")
|
||||
cls.bigG = nx.grid_2d_graph(25, 25) # > 500 nodes for sparse
|
||||
|
||||
@staticmethod
|
||||
def collect_node_distances(positions):
|
||||
distances = []
|
||||
prev_val = None
|
||||
for k in positions:
|
||||
if prev_val is not None:
|
||||
diff = positions[k] - prev_val
|
||||
distances.append(numpy.dot(diff, diff) ** 0.5)
|
||||
prev_val = positions[k]
|
||||
return distances
|
||||
|
||||
def test_spring_fixed_without_pos(self):
|
||||
G = nx.path_graph(4)
|
||||
pytest.raises(ValueError, nx.spring_layout, G, fixed=[0])
|
||||
pos = {0: (1, 1), 2: (0, 0)}
|
||||
pytest.raises(ValueError, nx.spring_layout, G, fixed=[0, 1], pos=pos)
|
||||
nx.spring_layout(G, fixed=[0, 2], pos=pos) # No ValueError
|
||||
|
||||
def test_spring_init_pos(self):
|
||||
# Tests GH #2448
|
||||
import math
|
||||
|
||||
G = nx.Graph()
|
||||
G.add_edges_from([(0, 1), (1, 2), (2, 0), (2, 3)])
|
||||
|
||||
init_pos = {0: (0.0, 0.0)}
|
||||
fixed_pos = [0]
|
||||
pos = nx.fruchterman_reingold_layout(G, pos=init_pos, fixed=fixed_pos)
|
||||
has_nan = any(math.isnan(c) for coords in pos.values() for c in coords)
|
||||
assert not has_nan, "values should not be nan"
|
||||
|
||||
def test_smoke_empty_graph(self):
|
||||
G = []
|
||||
nx.random_layout(G)
|
||||
nx.circular_layout(G)
|
||||
nx.planar_layout(G)
|
||||
nx.spring_layout(G)
|
||||
nx.fruchterman_reingold_layout(G)
|
||||
nx.spectral_layout(G)
|
||||
nx.shell_layout(G)
|
||||
nx.bipartite_layout(G, G)
|
||||
nx.spiral_layout(G)
|
||||
nx.multipartite_layout(G)
|
||||
nx.kamada_kawai_layout(G)
|
||||
|
||||
def test_smoke_int(self):
|
||||
G = self.Gi
|
||||
nx.random_layout(G)
|
||||
nx.circular_layout(G)
|
||||
nx.planar_layout(G)
|
||||
nx.spring_layout(G)
|
||||
nx.fruchterman_reingold_layout(G)
|
||||
nx.fruchterman_reingold_layout(self.bigG)
|
||||
nx.spectral_layout(G)
|
||||
nx.spectral_layout(G.to_directed())
|
||||
nx.spectral_layout(self.bigG)
|
||||
nx.spectral_layout(self.bigG.to_directed())
|
||||
nx.shell_layout(G)
|
||||
nx.spiral_layout(G)
|
||||
nx.kamada_kawai_layout(G)
|
||||
nx.kamada_kawai_layout(G, dim=1)
|
||||
nx.kamada_kawai_layout(G, dim=3)
|
||||
|
||||
def test_smoke_string(self):
|
||||
G = self.Gs
|
||||
nx.random_layout(G)
|
||||
nx.circular_layout(G)
|
||||
nx.planar_layout(G)
|
||||
nx.spring_layout(G)
|
||||
nx.fruchterman_reingold_layout(G)
|
||||
nx.spectral_layout(G)
|
||||
nx.shell_layout(G)
|
||||
nx.spiral_layout(G)
|
||||
nx.kamada_kawai_layout(G)
|
||||
nx.kamada_kawai_layout(G, dim=1)
|
||||
nx.kamada_kawai_layout(G, dim=3)
|
||||
|
||||
def check_scale_and_center(self, pos, scale, center):
|
||||
center = numpy.array(center)
|
||||
low = center - scale
|
||||
hi = center + scale
|
||||
vpos = numpy.array(list(pos.values()))
|
||||
length = vpos.max(0) - vpos.min(0)
|
||||
assert (length <= 2 * scale).all()
|
||||
assert (vpos >= low).all()
|
||||
assert (vpos <= hi).all()
|
||||
|
||||
def test_scale_and_center_arg(self):
|
||||
sc = self.check_scale_and_center
|
||||
c = (4, 5)
|
||||
G = nx.complete_graph(9)
|
||||
G.add_node(9)
|
||||
sc(nx.random_layout(G, center=c), scale=0.5, center=(4.5, 5.5))
|
||||
# rest can have 2*scale length: [-scale, scale]
|
||||
sc(nx.spring_layout(G, scale=2, center=c), scale=2, center=c)
|
||||
sc(nx.spectral_layout(G, scale=2, center=c), scale=2, center=c)
|
||||
sc(nx.circular_layout(G, scale=2, center=c), scale=2, center=c)
|
||||
sc(nx.shell_layout(G, scale=2, center=c), scale=2, center=c)
|
||||
sc(nx.spiral_layout(G, scale=2, center=c), scale=2, center=c)
|
||||
sc(nx.kamada_kawai_layout(G, scale=2, center=c), scale=2, center=c)
|
||||
|
||||
c = (2, 3, 5)
|
||||
sc(nx.kamada_kawai_layout(G, dim=3, scale=2, center=c), scale=2, center=c)
|
||||
|
||||
def test_planar_layout_non_planar_input(self):
|
||||
G = nx.complete_graph(9)
|
||||
pytest.raises(nx.NetworkXException, nx.planar_layout, G)
|
||||
|
||||
def test_smoke_planar_layout_embedding_input(self):
|
||||
embedding = nx.PlanarEmbedding()
|
||||
embedding.set_data({0: [1, 2], 1: [0, 2], 2: [0, 1]})
|
||||
nx.planar_layout(embedding)
|
||||
|
||||
def test_default_scale_and_center(self):
|
||||
sc = self.check_scale_and_center
|
||||
c = (0, 0)
|
||||
G = nx.complete_graph(9)
|
||||
G.add_node(9)
|
||||
sc(nx.random_layout(G), scale=0.5, center=(0.5, 0.5))
|
||||
sc(nx.spring_layout(G), scale=1, center=c)
|
||||
sc(nx.spectral_layout(G), scale=1, center=c)
|
||||
sc(nx.circular_layout(G), scale=1, center=c)
|
||||
sc(nx.shell_layout(G), scale=1, center=c)
|
||||
sc(nx.spiral_layout(G), scale=1, center=c)
|
||||
sc(nx.kamada_kawai_layout(G), scale=1, center=c)
|
||||
|
||||
c = (0, 0, 0)
|
||||
sc(nx.kamada_kawai_layout(G, dim=3), scale=1, center=c)
|
||||
|
||||
def test_circular_planar_and_shell_dim_error(self):
|
||||
G = nx.path_graph(4)
|
||||
pytest.raises(ValueError, nx.circular_layout, G, dim=1)
|
||||
pytest.raises(ValueError, nx.shell_layout, G, dim=1)
|
||||
pytest.raises(ValueError, nx.shell_layout, G, dim=3)
|
||||
pytest.raises(ValueError, nx.planar_layout, G, dim=1)
|
||||
pytest.raises(ValueError, nx.planar_layout, G, dim=3)
|
||||
|
||||
def test_adjacency_interface_numpy(self):
|
||||
A = nx.to_numpy_array(self.Gs)
|
||||
pos = nx.drawing.layout._fruchterman_reingold(A)
|
||||
assert pos.shape == (6, 2)
|
||||
pos = nx.drawing.layout._fruchterman_reingold(A, dim=3)
|
||||
assert pos.shape == (6, 3)
|
||||
pos = nx.drawing.layout._sparse_fruchterman_reingold(A)
|
||||
assert pos.shape == (6, 2)
|
||||
|
||||
def test_adjacency_interface_scipy(self):
|
||||
A = nx.to_scipy_sparse_matrix(self.Gs, dtype="d")
|
||||
pos = nx.drawing.layout._sparse_fruchterman_reingold(A)
|
||||
assert pos.shape == (6, 2)
|
||||
pos = nx.drawing.layout._sparse_spectral(A)
|
||||
assert pos.shape == (6, 2)
|
||||
pos = nx.drawing.layout._sparse_fruchterman_reingold(A, dim=3)
|
||||
assert pos.shape == (6, 3)
|
||||
|
||||
def test_single_nodes(self):
|
||||
G = nx.path_graph(1)
|
||||
vpos = nx.shell_layout(G)
|
||||
assert not vpos[0].any()
|
||||
G = nx.path_graph(4)
|
||||
vpos = nx.shell_layout(G, [[0], [1, 2], [3]])
|
||||
assert not vpos[0].any()
|
||||
assert vpos[3].any() # ensure node 3 not at origin (#3188)
|
||||
assert numpy.linalg.norm(vpos[3]) <= 1 # ensure node 3 fits (#3753)
|
||||
vpos = nx.shell_layout(G, [[0], [1, 2], [3]], rotate=0)
|
||||
assert numpy.linalg.norm(vpos[3]) <= 1 # ensure node 3 fits (#3753)
|
||||
|
||||
def test_smoke_initial_pos_fruchterman_reingold(self):
|
||||
pos = nx.circular_layout(self.Gi)
|
||||
npos = nx.fruchterman_reingold_layout(self.Gi, pos=pos)
|
||||
|
||||
def test_fixed_node_fruchterman_reingold(self):
|
||||
# Dense version (numpy based)
|
||||
pos = nx.circular_layout(self.Gi)
|
||||
npos = nx.spring_layout(self.Gi, pos=pos, fixed=[(0, 0)])
|
||||
assert tuple(pos[(0, 0)]) == tuple(npos[(0, 0)])
|
||||
# Sparse version (scipy based)
|
||||
pos = nx.circular_layout(self.bigG)
|
||||
npos = nx.spring_layout(self.bigG, pos=pos, fixed=[(0, 0)])
|
||||
for axis in range(2):
|
||||
assert almost_equal(pos[(0, 0)][axis], npos[(0, 0)][axis])
|
||||
|
||||
def test_center_parameter(self):
|
||||
G = nx.path_graph(1)
|
||||
nx.random_layout(G, center=(1, 1))
|
||||
vpos = nx.circular_layout(G, center=(1, 1))
|
||||
assert tuple(vpos[0]) == (1, 1)
|
||||
vpos = nx.planar_layout(G, center=(1, 1))
|
||||
assert tuple(vpos[0]) == (1, 1)
|
||||
vpos = nx.spring_layout(G, center=(1, 1))
|
||||
assert tuple(vpos[0]) == (1, 1)
|
||||
vpos = nx.fruchterman_reingold_layout(G, center=(1, 1))
|
||||
assert tuple(vpos[0]) == (1, 1)
|
||||
vpos = nx.spectral_layout(G, center=(1, 1))
|
||||
assert tuple(vpos[0]) == (1, 1)
|
||||
vpos = nx.shell_layout(G, center=(1, 1))
|
||||
assert tuple(vpos[0]) == (1, 1)
|
||||
vpos = nx.spiral_layout(G, center=(1, 1))
|
||||
assert tuple(vpos[0]) == (1, 1)
|
||||
|
||||
def test_center_wrong_dimensions(self):
|
||||
G = nx.path_graph(1)
|
||||
assert id(nx.spring_layout) == id(nx.fruchterman_reingold_layout)
|
||||
pytest.raises(ValueError, nx.random_layout, G, center=(1, 1, 1))
|
||||
pytest.raises(ValueError, nx.circular_layout, G, center=(1, 1, 1))
|
||||
pytest.raises(ValueError, nx.planar_layout, G, center=(1, 1, 1))
|
||||
pytest.raises(ValueError, nx.spring_layout, G, center=(1, 1, 1))
|
||||
pytest.raises(ValueError, nx.spring_layout, G, dim=3, center=(1, 1))
|
||||
pytest.raises(ValueError, nx.spectral_layout, G, center=(1, 1, 1))
|
||||
pytest.raises(ValueError, nx.spectral_layout, G, dim=3, center=(1, 1))
|
||||
pytest.raises(ValueError, nx.shell_layout, G, center=(1, 1, 1))
|
||||
pytest.raises(ValueError, nx.spiral_layout, G, center=(1, 1, 1))
|
||||
pytest.raises(ValueError, nx.kamada_kawai_layout, G, center=(1, 1, 1))
|
||||
|
||||
def test_empty_graph(self):
|
||||
G = nx.empty_graph()
|
||||
vpos = nx.random_layout(G, center=(1, 1))
|
||||
assert vpos == {}
|
||||
vpos = nx.circular_layout(G, center=(1, 1))
|
||||
assert vpos == {}
|
||||
vpos = nx.planar_layout(G, center=(1, 1))
|
||||
assert vpos == {}
|
||||
vpos = nx.bipartite_layout(G, G)
|
||||
assert vpos == {}
|
||||
vpos = nx.spring_layout(G, center=(1, 1))
|
||||
assert vpos == {}
|
||||
vpos = nx.fruchterman_reingold_layout(G, center=(1, 1))
|
||||
assert vpos == {}
|
||||
vpos = nx.spectral_layout(G, center=(1, 1))
|
||||
assert vpos == {}
|
||||
vpos = nx.shell_layout(G, center=(1, 1))
|
||||
assert vpos == {}
|
||||
vpos = nx.spiral_layout(G, center=(1, 1))
|
||||
assert vpos == {}
|
||||
vpos = nx.multipartite_layout(G, center=(1, 1))
|
||||
assert vpos == {}
|
||||
vpos = nx.kamada_kawai_layout(G, center=(1, 1))
|
||||
assert vpos == {}
|
||||
|
||||
def test_bipartite_layout(self):
|
||||
G = nx.complete_bipartite_graph(3, 5)
|
||||
top, bottom = nx.bipartite.sets(G)
|
||||
|
||||
vpos = nx.bipartite_layout(G, top)
|
||||
assert len(vpos) == len(G)
|
||||
|
||||
top_x = vpos[list(top)[0]][0]
|
||||
bottom_x = vpos[list(bottom)[0]][0]
|
||||
for node in top:
|
||||
assert vpos[node][0] == top_x
|
||||
for node in bottom:
|
||||
assert vpos[node][0] == bottom_x
|
||||
|
||||
vpos = nx.bipartite_layout(
|
||||
G, top, align="horizontal", center=(2, 2), scale=2, aspect_ratio=1
|
||||
)
|
||||
assert len(vpos) == len(G)
|
||||
|
||||
top_y = vpos[list(top)[0]][1]
|
||||
bottom_y = vpos[list(bottom)[0]][1]
|
||||
for node in top:
|
||||
assert vpos[node][1] == top_y
|
||||
for node in bottom:
|
||||
assert vpos[node][1] == bottom_y
|
||||
|
||||
pytest.raises(ValueError, nx.bipartite_layout, G, top, align="foo")
|
||||
|
||||
def test_multipartite_layout(self):
|
||||
sizes = (0, 5, 7, 2, 8)
|
||||
G = nx.complete_multipartite_graph(*sizes)
|
||||
|
||||
vpos = nx.multipartite_layout(G)
|
||||
assert len(vpos) == len(G)
|
||||
|
||||
start = 0
|
||||
for n in sizes:
|
||||
end = start + n
|
||||
assert all(vpos[start][0] == vpos[i][0] for i in range(start + 1, end))
|
||||
start += n
|
||||
|
||||
vpos = nx.multipartite_layout(G, align="horizontal", scale=2, center=(2, 2))
|
||||
assert len(vpos) == len(G)
|
||||
|
||||
start = 0
|
||||
for n in sizes:
|
||||
end = start + n
|
||||
assert all(vpos[start][1] == vpos[i][1] for i in range(start + 1, end))
|
||||
start += n
|
||||
|
||||
pytest.raises(ValueError, nx.multipartite_layout, G, align="foo")
|
||||
|
||||
def test_kamada_kawai_costfn_1d(self):
|
||||
costfn = nx.drawing.layout._kamada_kawai_costfn
|
||||
|
||||
pos = numpy.array([4.0, 7.0])
|
||||
invdist = 1 / numpy.array([[0.1, 2.0], [2.0, 0.3]])
|
||||
|
||||
cost, grad = costfn(pos, numpy, invdist, meanweight=0, dim=1)
|
||||
|
||||
assert almost_equal(cost, ((3 / 2.0 - 1) ** 2))
|
||||
assert almost_equal(grad[0], -0.5)
|
||||
assert almost_equal(grad[1], 0.5)
|
||||
|
||||
def check_kamada_kawai_costfn(self, pos, invdist, meanwt, dim):
|
||||
costfn = nx.drawing.layout._kamada_kawai_costfn
|
||||
|
||||
cost, grad = costfn(pos.ravel(), numpy, invdist, meanweight=meanwt, dim=dim)
|
||||
|
||||
expected_cost = 0.5 * meanwt * numpy.sum(numpy.sum(pos, axis=0) ** 2)
|
||||
for i in range(pos.shape[0]):
|
||||
for j in range(i + 1, pos.shape[0]):
|
||||
diff = numpy.linalg.norm(pos[i] - pos[j])
|
||||
expected_cost += (diff * invdist[i][j] - 1.0) ** 2
|
||||
|
||||
assert almost_equal(cost, expected_cost)
|
||||
|
||||
dx = 1e-4
|
||||
for nd in range(pos.shape[0]):
|
||||
for dm in range(pos.shape[1]):
|
||||
idx = nd * pos.shape[1] + dm
|
||||
pos0 = pos.flatten()
|
||||
|
||||
pos0[idx] += dx
|
||||
cplus = costfn(
|
||||
pos0, numpy, invdist, meanweight=meanwt, dim=pos.shape[1]
|
||||
)[0]
|
||||
|
||||
pos0[idx] -= 2 * dx
|
||||
cminus = costfn(
|
||||
pos0, numpy, invdist, meanweight=meanwt, dim=pos.shape[1]
|
||||
)[0]
|
||||
|
||||
assert almost_equal(grad[idx], (cplus - cminus) / (2 * dx), places=5)
|
||||
|
||||
def test_kamada_kawai_costfn(self):
|
||||
invdist = 1 / numpy.array([[0.1, 2.1, 1.7], [2.1, 0.2, 0.6], [1.7, 0.6, 0.3]])
|
||||
meanwt = 0.3
|
||||
|
||||
# 2d
|
||||
pos = numpy.array([[1.3, -3.2], [2.7, -0.3], [5.1, 2.5]])
|
||||
|
||||
self.check_kamada_kawai_costfn(pos, invdist, meanwt, 2)
|
||||
|
||||
# 3d
|
||||
pos = numpy.array([[0.9, 8.6, -8.7], [-10, -0.5, -7.1], [9.1, -8.1, 1.6]])
|
||||
|
||||
self.check_kamada_kawai_costfn(pos, invdist, meanwt, 3)
|
||||
|
||||
def test_spiral_layout(self):
|
||||
|
||||
G = self.Gs
|
||||
|
||||
# a lower value of resolution should result in a more compact layout
|
||||
# intuitively, the total distance from the start and end nodes
|
||||
# via each node in between (transiting through each) will be less,
|
||||
# assuming rescaling does not occur on the computed node positions
|
||||
pos_standard = nx.spiral_layout(G, resolution=0.35)
|
||||
pos_tighter = nx.spiral_layout(G, resolution=0.34)
|
||||
distances = self.collect_node_distances(pos_standard)
|
||||
distances_tighter = self.collect_node_distances(pos_tighter)
|
||||
assert sum(distances) > sum(distances_tighter)
|
||||
|
||||
# return near-equidistant points after the first value if set to true
|
||||
pos_equidistant = nx.spiral_layout(G, equidistant=True)
|
||||
distances_equidistant = self.collect_node_distances(pos_equidistant)
|
||||
for d in range(1, len(distances_equidistant) - 1):
|
||||
# test similarity to two decimal places
|
||||
assert almost_equal(
|
||||
distances_equidistant[d], distances_equidistant[d + 1], 2
|
||||
)
|
||||
|
||||
def test_rescale_layout_dict(self):
|
||||
G = nx.empty_graph()
|
||||
vpos = nx.random_layout(G, center=(1, 1))
|
||||
assert nx.rescale_layout_dict(vpos) == {}
|
||||
|
||||
G = nx.empty_graph(2)
|
||||
vpos = {0: (0.0, 0.0), 1: (1.0, 1.0)}
|
||||
s_vpos = nx.rescale_layout_dict(vpos)
|
||||
norm = numpy.linalg.norm
|
||||
assert norm([sum(x) for x in zip(*s_vpos.values())]) < 1e-6
|
||||
|
||||
G = nx.empty_graph(3)
|
||||
vpos = {0: (0, 0), 1: (1, 1), 2: (0.5, 0.5)}
|
||||
s_vpos = nx.rescale_layout_dict(vpos)
|
||||
assert s_vpos == {0: (-1, -1), 1: (1, 1), 2: (0, 0)}
|
||||
s_vpos = nx.rescale_layout_dict(vpos, scale=2)
|
||||
assert s_vpos == {0: (-2, -2), 1: (2, 2), 2: (0, 0)}
|
94
venv/Lib/site-packages/networkx/drawing/tests/test_pydot.py
Normal file
94
venv/Lib/site-packages/networkx/drawing/tests/test_pydot.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
"""Unit tests for pydot drawing functions."""
|
||||
from io import StringIO
|
||||
import tempfile
|
||||
import networkx as nx
|
||||
from networkx.testing import assert_graphs_equal
|
||||
|
||||
import pytest
|
||||
|
||||
pydot = pytest.importorskip("pydot")
|
||||
|
||||
|
||||
class TestPydot:
|
||||
def pydot_checks(self, G, prog):
|
||||
"""
|
||||
Validate :mod:`pydot`-based usage of the passed NetworkX graph with the
|
||||
passed basename of an external GraphViz command (e.g., `dot`, `neato`).
|
||||
"""
|
||||
|
||||
# Set the name of this graph to... "G". Failing to do so will
|
||||
# subsequently trip an assertion expecting this name.
|
||||
G.graph["name"] = "G"
|
||||
|
||||
# Add arbitrary nodes and edges to the passed empty graph.
|
||||
G.add_edges_from([("A", "B"), ("A", "C"), ("B", "C"), ("A", "D")])
|
||||
G.add_node("E")
|
||||
|
||||
# Validate layout of this graph with the passed GraphViz command.
|
||||
graph_layout = nx.nx_pydot.pydot_layout(G, prog=prog)
|
||||
assert isinstance(graph_layout, dict)
|
||||
|
||||
# Convert this graph into a "pydot.Dot" instance.
|
||||
P = nx.nx_pydot.to_pydot(G)
|
||||
|
||||
# Convert this "pydot.Dot" instance back into a graph of the same type.
|
||||
G2 = G.__class__(nx.nx_pydot.from_pydot(P))
|
||||
|
||||
# Validate the original and resulting graphs to be the same.
|
||||
assert_graphs_equal(G, G2)
|
||||
|
||||
# Serialize this "pydot.Dot" instance to a temporary file in dot format
|
||||
fname = tempfile.mktemp()
|
||||
P.write_raw(fname)
|
||||
|
||||
# Deserialize a list of new "pydot.Dot" instances back from this file.
|
||||
Pin_list = pydot.graph_from_dot_file(path=fname, encoding="utf-8")
|
||||
|
||||
# Validate this file to contain only one graph.
|
||||
assert len(Pin_list) == 1
|
||||
|
||||
# The single "pydot.Dot" instance deserialized from this file.
|
||||
Pin = Pin_list[0]
|
||||
|
||||
# Sorted list of all nodes in the original "pydot.Dot" instance.
|
||||
n1 = sorted([p.get_name() for p in P.get_node_list()])
|
||||
|
||||
# Sorted list of all nodes in the deserialized "pydot.Dot" instance.
|
||||
n2 = sorted([p.get_name() for p in Pin.get_node_list()])
|
||||
|
||||
# Validate these instances to contain the same nodes.
|
||||
assert n1 == n2
|
||||
|
||||
# Sorted list of all edges in the original "pydot.Dot" instance.
|
||||
e1 = sorted([(e.get_source(), e.get_destination()) for e in P.get_edge_list()])
|
||||
|
||||
# Sorted list of all edges in the original "pydot.Dot" instance.
|
||||
e2 = sorted(
|
||||
[(e.get_source(), e.get_destination()) for e in Pin.get_edge_list()]
|
||||
)
|
||||
|
||||
# Validate these instances to contain the same edges.
|
||||
assert e1 == e2
|
||||
|
||||
# Deserialize a new graph of the same type back from this file.
|
||||
Hin = nx.nx_pydot.read_dot(fname)
|
||||
Hin = G.__class__(Hin)
|
||||
|
||||
# Validate the original and resulting graphs to be the same.
|
||||
assert_graphs_equal(G, Hin)
|
||||
|
||||
def test_undirected(self):
|
||||
self.pydot_checks(nx.Graph(), prog="neato")
|
||||
|
||||
def test_directed(self):
|
||||
self.pydot_checks(nx.DiGraph(), prog="dot")
|
||||
|
||||
def test_read_write(self):
|
||||
G = nx.MultiGraph()
|
||||
G.graph["name"] = "G"
|
||||
G.add_edge("1", "2", key="0") # read assumes strings
|
||||
fh = StringIO()
|
||||
nx.nx_pydot.write_dot(G, fh)
|
||||
fh.seek(0)
|
||||
H = nx.nx_pydot.read_dot(fh)
|
||||
assert_graphs_equal(G, H)
|
257
venv/Lib/site-packages/networkx/drawing/tests/test_pylab.py
Normal file
257
venv/Lib/site-packages/networkx/drawing/tests/test_pylab.py
Normal file
|
@ -0,0 +1,257 @@
|
|||
"""Unit tests for matplotlib drawing functions."""
|
||||
import os
|
||||
import itertools
|
||||
import pytest
|
||||
|
||||
mpl = pytest.importorskip("matplotlib")
|
||||
mpl.use("PS")
|
||||
plt = pytest.importorskip("matplotlib.pyplot")
|
||||
plt.rcParams["text.usetex"] = False
|
||||
|
||||
import networkx as nx
|
||||
|
||||
|
||||
class TestPylab:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
cls.G = nx.barbell_graph(4, 6)
|
||||
|
||||
def test_draw(self):
|
||||
try:
|
||||
functions = [
|
||||
nx.draw_circular,
|
||||
nx.draw_kamada_kawai,
|
||||
nx.draw_planar,
|
||||
nx.draw_random,
|
||||
nx.draw_spectral,
|
||||
nx.draw_spring,
|
||||
nx.draw_shell,
|
||||
]
|
||||
options = [{"node_color": "black", "node_size": 100, "width": 3}]
|
||||
for function, option in itertools.product(functions, options):
|
||||
function(self.G, **option)
|
||||
plt.savefig("test.ps")
|
||||
|
||||
finally:
|
||||
try:
|
||||
os.unlink("test.ps")
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def test_draw_shell_nlist(self):
|
||||
try:
|
||||
nlist = [list(range(4)), list(range(4, 10)), list(range(10, 14))]
|
||||
nx.draw_shell(self.G, nlist=nlist)
|
||||
plt.savefig("test.ps")
|
||||
finally:
|
||||
try:
|
||||
os.unlink("test.ps")
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def test_edge_colormap(self):
|
||||
colors = range(self.G.number_of_edges())
|
||||
nx.draw_spring(
|
||||
self.G, edge_color=colors, width=4, edge_cmap=plt.cm.Blues, with_labels=True
|
||||
)
|
||||
# plt.show()
|
||||
|
||||
def test_arrows(self):
|
||||
nx.draw_spring(self.G.to_directed())
|
||||
# plt.show()
|
||||
|
||||
def test_edge_colors_and_widths(self):
|
||||
pos = nx.circular_layout(self.G)
|
||||
for G in (self.G, self.G.to_directed()):
|
||||
nx.draw_networkx_nodes(G, pos, node_color=[(1.0, 1.0, 0.2, 0.5)])
|
||||
nx.draw_networkx_labels(G, pos)
|
||||
# edge with default color and width
|
||||
nx.draw_networkx_edges(
|
||||
G, pos, edgelist=[(0, 1)], width=None, edge_color=None
|
||||
)
|
||||
# edges with global color strings and widths in lists
|
||||
nx.draw_networkx_edges(
|
||||
G, pos, edgelist=[(0, 2), (0, 3)], width=[3], edge_color=["r"]
|
||||
)
|
||||
# edges with color strings and widths for each edge
|
||||
nx.draw_networkx_edges(
|
||||
G, pos, edgelist=[(0, 2), (0, 3)], width=[1, 3], edge_color=["r", "b"]
|
||||
)
|
||||
# edges with fewer color strings and widths than edges
|
||||
nx.draw_networkx_edges(
|
||||
G,
|
||||
pos,
|
||||
edgelist=[(1, 2), (1, 3), (2, 3), (3, 4)],
|
||||
width=[1, 3],
|
||||
edge_color=["g", "m", "c"],
|
||||
)
|
||||
# edges with more color strings and widths than edges
|
||||
nx.draw_networkx_edges(
|
||||
G,
|
||||
pos,
|
||||
edgelist=[(3, 4)],
|
||||
width=[1, 2, 3, 4],
|
||||
edge_color=["r", "b", "g", "k"],
|
||||
)
|
||||
# with rgb tuple and 3 edges - is interpreted with cmap
|
||||
nx.draw_networkx_edges(
|
||||
G, pos, edgelist=[(4, 5), (5, 6), (6, 7)], edge_color=(1.0, 0.4, 0.3)
|
||||
)
|
||||
# with rgb tuple in list
|
||||
nx.draw_networkx_edges(
|
||||
G, pos, edgelist=[(7, 8), (8, 9)], edge_color=[(0.4, 1.0, 0.0)]
|
||||
)
|
||||
# with rgba tuple and 4 edges - is interpretted with cmap
|
||||
nx.draw_networkx_edges(
|
||||
G,
|
||||
pos,
|
||||
edgelist=[(9, 10), (10, 11), (10, 12), (10, 13)],
|
||||
edge_color=(0.0, 1.0, 1.0, 0.5),
|
||||
)
|
||||
# with rgba tuple in list
|
||||
nx.draw_networkx_edges(
|
||||
G,
|
||||
pos,
|
||||
edgelist=[(9, 10), (10, 11), (10, 12), (10, 13)],
|
||||
edge_color=[(0.0, 1.0, 1.0, 0.5)],
|
||||
)
|
||||
# with color string and global alpha
|
||||
nx.draw_networkx_edges(
|
||||
G, pos, edgelist=[(11, 12), (11, 13)], edge_color="purple", alpha=0.2
|
||||
)
|
||||
# with color string in a list
|
||||
nx.draw_networkx_edges(
|
||||
G, pos, edgelist=[(11, 12), (11, 13)], edge_color=["purple"]
|
||||
)
|
||||
# with single edge and hex color string
|
||||
nx.draw_networkx_edges(G, pos, edgelist=[(12, 13)], edge_color="#1f78b4f0")
|
||||
|
||||
# edge_color as numeric using vmin, vmax
|
||||
nx.draw_networkx_edges(
|
||||
G,
|
||||
pos,
|
||||
edgelist=[(7, 8), (8, 9)],
|
||||
edge_color=[0.2, 0.5],
|
||||
edge_vmin=0.1,
|
||||
edge_vmax=0.6,
|
||||
)
|
||||
|
||||
# plt.show()
|
||||
|
||||
def test_labels_and_colors(self):
|
||||
G = nx.cubical_graph()
|
||||
pos = nx.spring_layout(G) # positions for all nodes
|
||||
# nodes
|
||||
nx.draw_networkx_nodes(
|
||||
G, pos, nodelist=[0, 1, 2, 3], node_color="r", node_size=500, alpha=0.75
|
||||
)
|
||||
nx.draw_networkx_nodes(
|
||||
G,
|
||||
pos,
|
||||
nodelist=[4, 5, 6, 7],
|
||||
node_color="b",
|
||||
node_size=500,
|
||||
alpha=[0.25, 0.5, 0.75, 1.0],
|
||||
)
|
||||
# edges
|
||||
nx.draw_networkx_edges(G, pos, width=1.0, alpha=0.5)
|
||||
nx.draw_networkx_edges(
|
||||
G,
|
||||
pos,
|
||||
edgelist=[(0, 1), (1, 2), (2, 3), (3, 0)],
|
||||
width=8,
|
||||
alpha=0.5,
|
||||
edge_color="r",
|
||||
)
|
||||
nx.draw_networkx_edges(
|
||||
G,
|
||||
pos,
|
||||
edgelist=[(4, 5), (5, 6), (6, 7), (7, 4)],
|
||||
width=8,
|
||||
alpha=0.5,
|
||||
edge_color="b",
|
||||
)
|
||||
nx.draw_networkx_edges(
|
||||
G,
|
||||
pos,
|
||||
edgelist=[(4, 5), (5, 6), (6, 7), (7, 4)],
|
||||
min_source_margin=0.5,
|
||||
min_target_margin=0.75,
|
||||
width=8,
|
||||
edge_color="b",
|
||||
)
|
||||
# some math labels
|
||||
labels = {}
|
||||
labels[0] = r"$a$"
|
||||
labels[1] = r"$b$"
|
||||
labels[2] = r"$c$"
|
||||
labels[3] = r"$d$"
|
||||
labels[4] = r"$\alpha$"
|
||||
labels[5] = r"$\beta$"
|
||||
labels[6] = r"$\gamma$"
|
||||
labels[7] = r"$\delta$"
|
||||
nx.draw_networkx_labels(G, pos, labels, font_size=16)
|
||||
nx.draw_networkx_edge_labels(G, pos, edge_labels=None, rotate=False)
|
||||
nx.draw_networkx_edge_labels(G, pos, edge_labels={(4, 5): "4-5"})
|
||||
# plt.show()
|
||||
|
||||
def test_axes(self):
|
||||
fig, ax = plt.subplots()
|
||||
nx.draw(self.G, ax=ax)
|
||||
|
||||
def test_empty_graph(self):
|
||||
G = nx.Graph()
|
||||
nx.draw(G)
|
||||
|
||||
def test_draw_empty_nodes_return_values(self):
|
||||
# See Issue #3833
|
||||
from matplotlib.collections import PathCollection, LineCollection
|
||||
|
||||
G = nx.Graph([(1, 2), (2, 3)])
|
||||
DG = nx.DiGraph([(1, 2), (2, 3)])
|
||||
pos = nx.circular_layout(G)
|
||||
assert isinstance(nx.draw_networkx_nodes(G, pos, nodelist=[]), PathCollection)
|
||||
assert isinstance(nx.draw_networkx_nodes(DG, pos, nodelist=[]), PathCollection)
|
||||
|
||||
# drawing empty edges either return an empty LineCollection or empty list.
|
||||
assert isinstance(
|
||||
nx.draw_networkx_edges(G, pos, edgelist=[], arrows=True), LineCollection
|
||||
)
|
||||
assert isinstance(
|
||||
nx.draw_networkx_edges(G, pos, edgelist=[], arrows=False), LineCollection
|
||||
)
|
||||
assert isinstance(
|
||||
nx.draw_networkx_edges(DG, pos, edgelist=[], arrows=False), LineCollection
|
||||
)
|
||||
assert nx.draw_networkx_edges(DG, pos, edgelist=[], arrows=True) == []
|
||||
|
||||
def test_multigraph_edgelist_tuples(self):
|
||||
# See Issue #3295
|
||||
G = nx.path_graph(3, create_using=nx.MultiDiGraph)
|
||||
nx.draw_networkx(G, edgelist=[(0, 1, 0)])
|
||||
nx.draw_networkx(G, edgelist=[(0, 1, 0)], node_size=[10, 20, 0])
|
||||
|
||||
def test_alpha_iter(self):
|
||||
pos = nx.random_layout(self.G)
|
||||
# with fewer alpha elements than nodes
|
||||
plt.subplot(131)
|
||||
nx.draw_networkx_nodes(self.G, pos, alpha=[0.1, 0.2])
|
||||
# with equal alpha elements and nodes
|
||||
num_nodes = len(self.G.nodes)
|
||||
alpha = [x / num_nodes for x in range(num_nodes)]
|
||||
colors = range(num_nodes)
|
||||
plt.subplot(132)
|
||||
nx.draw_networkx_nodes(self.G, pos, node_color=colors, alpha=alpha)
|
||||
# with more alpha elements than nodes
|
||||
alpha.append(1)
|
||||
plt.subplot(133)
|
||||
nx.draw_networkx_nodes(self.G, pos, alpha=alpha)
|
||||
|
||||
def test_error_invalid_kwds(self):
|
||||
with pytest.raises(ValueError, match="Received invalid argument"):
|
||||
nx.draw(self.G, foo="bar")
|
||||
|
||||
def test_np_edgelist(self):
|
||||
# see issue #4129
|
||||
np = pytest.importorskip("numpy")
|
||||
nx.draw_networkx(self.G, edgelist=np.array([(0, 2), (0, 3)]))
|
Loading…
Add table
Add a link
Reference in a new issue