def __init__(self, name, systems = []): self.name = name self.graph = Graph(name = name) self.subsystems = systems self.unique_edges = [] self.junctions = [] self.connections = [] self.connections_kwargs = [] self.components = []
def test_subgraphing(self): original_numbers = self._get_original_numbers() simple = Graph(name = 'simple') simple.add_node(x=0.0, y=0.0, name = 'A') simple.add_node(x=0.0, y=1.0, name = 'B') simple.connect('A', 'B', name = "I", directional = False) simple_copy = simple.copy(1.0, 0.0) super_graph = Graph(name = 'super_graph', graphs = [simple, simple_copy]) super_graph.connect('simple:A', 'simple(copy):B', name = 'II', directional = True) nodes = [('simple:A', Node(0.0, 0.0)), ('simple:B', Node(0.0, 1.0)), ('simple(copy):A', Node(1.0, 0.0)), ('simple(copy):B', Node(1.0, 1.0))] edges = [('simple:I', Edge('simple:A', 'simple:B', directional = False)), ('simple(copy):I', Edge('simple(copy):A', 'simple(copy):B', directional = False)), ('II', Edge('simple:A', 'simple(copy):B', directional = True))] numbers = (4, # anchored_nodes 3, # anchored_edges 0, # unique_nodes 1, # unique_anchored_edges 0, # unique_unanchored_edges 2, # subgraphs 2 # anchored_subgraphs ) self._check_graph(super_graph, 'super_graph', 'simple:A', True, nodes, edges, numbers) self._check_numbers(original_numbers, 8, 6, 3)
def test_copy(self): original_numbers = self._get_original_numbers() simple = Graph(name='simple') simple.add_node(x=0.0, y=0.0, name='A') simple.add_node(x=0.0, y=1.0, name='B') simple.connect('A', 'B', name="I", directional=False) simple_copy = simple.copy(0.0, 0.0) nodes = [('A', Node(0.0, 0.0)), ('B', Node(0.0, 1.0))] edges = [('I', Edge('A', 'B', directional=False))] numbers = ( 2, # anchored_nodes 1, # anchored_edges 2, # unique_nodes 1, # unique_anchored_edges 0, # unique_unanchored_edges 0, # subgraphs 0 # anchored_subgraphs ) self._check_graph(simple_copy, 'simple(copy)', 'A', True, nodes, edges, numbers) self._check_numbers(original_numbers, 6, 3, 2) for node, node_copy in zip(simple.nodes.values(), simple_copy.nodes.values()): self.assertEqual(node, node_copy) self.assertIsNot(node, node_copy) for edge, edge_copy in zip(simple.edges.values(), simple_copy.edges.values()): self.assertEqual(edge, edge_copy) self.assertIsNot(edge, edge_copy)
def test_add_node(self): original_numbers = self._get_original_numbers() simple = Graph(name = 'simple') simple.add_node(x=0.0, y=1.0, name = 'A') nodes = [('A', Node(0.0, 1.0))] edges = [] numbers = (1, # anchored_nodes 0, # anchored_edges 1, # unique_nodes 0, # unique_anchored_edges 0, # unique_unanchored_edges 0, # subgraphs 0 # anchored_subgraphs ) self._check_graph(simple, 'simple', 'A', False, nodes, edges, numbers) self._check_numbers(original_numbers, 2, 0, 1)
def test_add_node(self): original_numbers = self._get_original_numbers() simple = Graph(name='simple') simple.add_node(x=0.0, y=1.0, name='A') nodes = [('A', Node(0.0, 1.0))] edges = [] numbers = ( 1, # anchored_nodes 0, # anchored_edges 1, # unique_nodes 0, # unique_anchored_edges 0, # unique_unanchored_edges 0, # subgraphs 0 # anchored_subgraphs ) self._check_graph(simple, 'simple', 'A', False, nodes, edges, numbers) self._check_numbers(original_numbers, 2, 0, 1)
def __init__(self, center_of_rotation, **kwargs): Component.stats[self.__class__.__name__] += 1 super(Component, self).__init__(center_of_rotation, **kwargs) Transformation.__init__(self, center_of_rotation, **kwargs) self.name = process_name(None, kwargs) self.label_string = self.name self.graph = Graph(name=self.name) self._get_nodes() self._connect_nodes() self.face_color = process_face_color((1.0, 1.0, 1.0), kwargs) self.edge_color = process_edge_color((0.0, 0.0, 0.0), kwargs) self.line_width = process_line_width(1.5, kwargs) self.patch = None self._points = [] self._connections = []
def test_copy(self): original_numbers = self._get_original_numbers() simple = Graph(name = 'simple') simple.add_node(x=0.0, y=0.0, name = 'A') simple.add_node(x=0.0, y=1.0, name = 'B') simple.connect('A', 'B', name = "I", directional = False) simple_copy = simple.copy(0.0, 0.0) nodes = [('A', Node(0.0, 0.0)), ('B', Node(0.0, 1.0))] edges = [('I', Edge('A', 'B', directional = False))] numbers = (2, # anchored_nodes 1, # anchored_edges 2, # unique_nodes 1, # unique_anchored_edges 0, # unique_unanchored_edges 0, # subgraphs 0 # anchored_subgraphs ) self._check_graph(simple_copy, 'simple(copy)', 'A', True, nodes, edges, numbers) self._check_numbers(original_numbers, 6, 3, 2) for node, node_copy in zip(simple.nodes.values(), simple_copy.nodes.values()): self.assertEqual(node, node_copy) self.assertIsNot(node, node_copy) for edge, edge_copy in zip(simple.edges.values(), simple_copy.edges.values()): self.assertEqual(edge, edge_copy) self.assertIsNot(edge, edge_copy)
def test_instantiation(self): original_numbers = self._get_original_numbers() simple = Graph(name='simple') nodes = [] edges = [] numbers = ( 0, # anchored_nodes 0, # anchored_edges 0, # unique_nodes 0, # unique_anchored_edges 0, # unique_unanchored_edges 0, # subgraphs 0 # anchored_subgraphs ) self._check_graph(simple, 'simple', None, False, nodes, edges, numbers) self._check_numbers(original_numbers, 0, 0, 1)
def test_connect(self): original_numbers = self._get_original_numbers() simple = Graph(name='simple') simple.add_node(x=0.0, y=0.0, name='A') simple.add_node(x=0.0, y=1.0, name='B', anchor=True) simple.connect('A', 'B', name="I", directional=False) nodes = [('A', Node(0.0, 0.0)), ('B', Node(0.0, 1.0))] edges = [('I', Edge('A', 'B', directional=False))] numbers = ( 2, # anchored_nodes 1, # anchored_edges 2, # unique_nodes 1, # unique_anchored_edges 0, # unique_unanchored_edges 0, # subgraphs 0 # anchored_subgraphs ) self._check_graph(simple, 'simple', 'B', True, nodes, edges, numbers) self._check_numbers(original_numbers, 4, 2, 1)
def __init__(self, center_of_rotation, **kwargs): Component.stats[self.__class__.__name__] += 1 super(Component, self).__init__(center_of_rotation, **kwargs) Transformation.__init__(self, center_of_rotation, **kwargs) self.name = process_name(None, kwargs) self.label_string = self.name self.graph = Graph(name = self.name) self._get_nodes() self._connect_nodes() self.face_color = process_face_color((1.0, 1.0, 1.0), kwargs) self.edge_color = process_edge_color((0.0, 0.0, 0.0), kwargs) self.line_width = process_line_width(1.5, kwargs) self.patch = None self._points = [] self._connections = []
def test_connect(self): original_numbers = self._get_original_numbers() simple = Graph(name = 'simple') simple.add_node(x=0.0, y=0.0, name = 'A') simple.add_node(x=0.0, y=1.0, name = 'B', anchor = True) simple.connect('A', 'B', name = "I", directional = False) nodes = [('A', Node(0.0, 0.0)), ('B', Node(0.0, 1.0))] edges = [('I', Edge('A', 'B', directional = False))] numbers = (2, # anchored_nodes 1, # anchored_edges 2, # unique_nodes 1, # unique_anchored_edges 0, # unique_unanchored_edges 0, # subgraphs 0 # anchored_subgraphs ) self._check_graph(simple, 'simple', 'B', True, nodes, edges, numbers) self._check_numbers(original_numbers, 4, 2, 1)
from __future__ import print_function from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Labeled node test case.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt main = Graph(name='main') main.add_node(x=0.0, y=0.0, ll='bottom') main.add_node(x=1.0, y=0.0, ll='right') main.add_node(x=1.0, y=1.0, ll='top') main.add_node(x=0.0, y=1.0, ll='left') main.connect('Node 0', 'Node 1', label_location='bottom', label_angle=30.0) main.connect('Node 1', 'Node 2', label_location='top', label_angle=30.0) main.connect('Node 2', 'Node 3', label_location='top', label_angle=30.0) main.connect('Node 3', 'Node 0', label_location='top', label_angle=30.0) print(main.edges) GRAPH = Graph(name='graph', graphs=[main], node_line_width=2.0, node_radius=0.05) GRAPH.anchor_graph() print('Nodes are anchored:', GRAPH.anchored) print(GRAPH.general_info(), '\n') print(GRAPH)
from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Compounded graph test case.') command_line_parser.parse() from schematics import Graph from schematics import Canvas # ------------- pipe1 pipe1 = Graph(name = 'pipe1') pipe1.add_node(x=0.0, y=0.0, name = 'inlet') pipe1.add_node(1.0, 0.0, name = 'outlet') # pipe1.connect('inlet', 'outlet', name = 'internal', directional = False) pipe1.anchor = 'inlet' # ------------- pipe2 pipe2 = pipe1.copy(x=1.5, y=0.0, name = 'pipe2') pipe2.anchor = 'inlet' # ------------- long_pipe1 long_pipe1 = Graph(name = 'long_pipe1', graphs = [pipe1, pipe2])
def test_subgraphing(self): original_numbers = self._get_original_numbers() simple = Graph(name='simple') simple.add_node(x=0.0, y=0.0, name='A') simple.add_node(x=0.0, y=1.0, name='B') simple.connect('A', 'B', name="I", directional=False) simple_copy = simple.copy(1.0, 0.0) super_graph = Graph(name='super_graph', graphs=[simple, simple_copy]) super_graph.connect('simple:A', 'simple(copy):B', name='II', directional=True) nodes = [('simple:A', Node(0.0, 0.0)), ('simple:B', Node(0.0, 1.0)), ('simple(copy):A', Node(1.0, 0.0)), ('simple(copy):B', Node(1.0, 1.0))] edges = [('simple:I', Edge('simple:A', 'simple:B', directional=False)), ('simple(copy):I', Edge('simple(copy):A', 'simple(copy):B', directional=False)), ('II', Edge('simple:A', 'simple(copy):B', directional=True))] numbers = ( 4, # anchored_nodes 3, # anchored_edges 0, # unique_nodes 1, # unique_anchored_edges 0, # unique_unanchored_edges 2, # subgraphs 2 # anchored_subgraphs ) self._check_graph(super_graph, 'super_graph', 'simple:A', True, nodes, edges, numbers) self._check_numbers(original_numbers, 8, 6, 3)
def test_copying_with_subgraphing(self): original_numbers = self._get_original_numbers() pipe1 = Graph(name='pipe1') pipe1.add_node(x=0.0, y=0.0, name='inlet') pipe1.add_node(1.0, 0.0, name='outlet') pipe2 = pipe1.copy(x=1.5, y=0.0, name='pipe2') long_pipe1 = Graph(name='long_pipe1', graphs=[pipe1, pipe2]) long_pipe1.connect('pipe1:outlet', 'pipe2:inlet', name="junction") long_pipe1.connect('pipe1:inlet', 'pipe1:outlet', name="internal-connection1", directional=False) long_pipe1.connect('pipe2:inlet', 'pipe2:outlet', name="internal-connection2", directional=False) long_pipe2 = long_pipe1.copy(x=2.5, y=1.0, name='long_pipe2') long_pipe2.reflect(axis='y') circuit = Graph(name='circuit', graphs=[long_pipe1, long_pipe2]) circuit.connect('long_pipe1:pipe2:outlet', 'long_pipe2:pipe1:inlet', name="junction1") circuit.connect('long_pipe2:pipe2:outlet', 'long_pipe1:pipe1:inlet', name="junction2") nodes = [('long_pipe1:pipe1:inlet', Node(0.0, 0.0)), ('long_pipe1:pipe1:outlet', Node(1.0, 0.0)), ('long_pipe1:pipe2:inlet', Node(1.5, 0.0)), ('long_pipe1:pipe2:outlet', Node(2.5, 0.0)), ('long_pipe2:pipe1:inlet', Node(2.5, 1.0)), ('long_pipe2:pipe1:outlet', Node(1.5, 1.0)), ('long_pipe2:pipe2:inlet', Node(1.0, 1.0)), ('long_pipe2:pipe2:outlet', Node(0.0, 1.0))] edges = [('long_pipe1:junction', Edge('long_pipe1:pipe1:outlet', 'long_pipe1:pipe2:inlet', directional=True)), ('long_pipe1:internal-connection1', Edge('long_pipe1:pipe1:inlet', 'long_pipe1:pipe1:outlet', directional=False)), ('long_pipe1:internal-connection2', Edge('long_pipe1:pipe2:inlet', 'long_pipe1:pipe2:outlet', directional=False)), ('long_pipe2:junction', Edge('long_pipe2:pipe1:outlet', 'long_pipe2:pipe2:inlet', directional=True)), ('long_pipe2:internal-connection1', Edge('long_pipe2:pipe1:inlet', 'long_pipe2:pipe1:outlet', directional=False)), ('long_pipe2:internal-connection2', Edge('long_pipe2:pipe2:inlet', 'long_pipe2:pipe2:outlet', directional=False)), ('junction1', Edge('long_pipe1:pipe2:outlet', 'long_pipe2:pipe1:inlet', directional=True)), ('junction2', Edge('long_pipe2:pipe2:outlet', 'long_pipe1:pipe1:inlet', directional=True))] numbers = ( 8, # anchored_nodes 8, # anchored_edges 0, # unique_nodes 2, # unique_anchored_edges 0, # unique_unanchored_edges 2, # subgraphs 2 # anchored_subgraphs ) self._check_graph(circuit, 'circuit', 'long_pipe1:pipe1:inlet', True, nodes, edges, numbers) self._check_numbers(original_numbers, 16, 16, 7)
class Component(Label, Transformation): stats = {} def _connect_nodes(self): connected_pairs = [] for node0 in self.graph.nodes.keys(): for node1 in self.graph.nodes.keys(): if node0 != node1: pair0 = (node0, node1) pair1 = (node1, node0) if pair0 not in connected_pairs and pair1 not in connected_pairs: connected_pairs.append(pair0) self.graph.connect(node0, node1, directional=False) def __init__(self, center_of_rotation, **kwargs): Component.stats[self.__class__.__name__] += 1 super(Component, self).__init__(center_of_rotation, **kwargs) Transformation.__init__(self, center_of_rotation, **kwargs) self.name = process_name(None, kwargs) self.label_string = self.name self.graph = Graph(name=self.name) self._get_nodes() self._connect_nodes() self.face_color = process_face_color((1.0, 1.0, 1.0), kwargs) self.edge_color = process_edge_color((0.0, 0.0, 0.0), kwargs) self.line_width = process_line_width(1.5, kwargs) self.patch = None self._points = [] self._connections = [] def _get_path_data(self): Path = mpath.Path self._path_data = [(Path.MOVETO, self._points[0].to_tuple())] point_index = 0 last_point_index = len(self._points) - 1 last_connection_index = len(self._connections) - 1 for connection_index, connection in enumerate(self._connections): connection = connection.lower() # Line if connection == 'lineto': point_index += 1 if point_index <= last_point_index: self._path_data.append( (Path.LINETO, self._points[point_index].to_tuple())) elif connection_index == last_connection_index: self._path_data.append( (Path.LINETO, self._points[0].to_tuple())) else: sys.exit( "Error: Incorrect point and connection specification in custom" + "shape component " + self.__class__.__name__ + ". Ran out of " + "points before all connections could be made.") # Quadratic Bezier Curve elif connection == 'curve3': for i in range(2): point_index += 1 if point_index <= last_point_index: self._path_data.append( (Path.CURVE4, self._points[point_index].to_tuple())) elif (connection_index == last_connection_index) and (i == 1): self._path_data.append( (Path.CURVE4, self._points[0].to_tuple())) else: sys.exit( "Error: Incorrect point and connection specification in custom" + "shape component " + self.__class__.__name__ + ". Ran out of " + "points before all connections could be made.") # Cubic Bezier Curve elif connection == 'curve4': for i in range(3): point_index += 1 if point_index <= last_point_index: self._path_data.append( (Path.CURVE4, self._points[point_index].to_tuple())) elif (connection_index == last_connection_index) and (i == 2): self._path_data.append( (Path.CURVE4, self._points[0].to_tuple())) else: sys.exit( "Error: Incorrect point and connection specification in custom" + "shape component " + self.__class__.__name__ + ". Ran out of " + "points before all connections could be made.") else: sys.exit( "Error: Invalid connection specification in custom shape component " + self.__class__.__name__ + ".") if connection_index == last_connection_index: if point_index != len(self._points): sys.exit( "Error: Incorrect point and connection specification in custom" + "shape component " + self.__class__.__name__ + ". Too many points " + "specified for the connection types.") self._path_data.append((Path.CLOSEPOLY, self._points[0].to_tuple())) def move(self, x, y): self.center_of_rotation.x = x self.center_of_rotation.y = y def _get_shape(self): for point in self._points: self._reflect(point) self._rotate(point) self._get_path_data() self._codes, self._verts = zip(*self._path_data) self.path = mpath.Path(self._verts, self._codes) def draw_component(self): self._get_shape() self.graph.move(self.center_of_rotation.x, self.center_of_rotation.y) self.graph.reflect(self.reflect) self.graph.rotate(self.angle) self.patches = [ mpatches.PathPatch(self.path, facecolor=self.face_color, edgecolor=self.edge_color, linewidth=self.line_width) ] return self.patches # Error messages def _get_nodes(self): sys.exit('Error: Must define "_get_nodes" method in the ' + self.__class__.__name__ + ' class.')
from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Shifting edge label.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt from math import sqrt main = Graph(name = 'main') main.add_node(x=0.0, y=0.0, name = 'A', ll = 'bottom') main.add_node(x=1.0, y=0.0, name = 'B', ll = 'right') main.connect('A', 'B', name = '1', ll = 'top', la = 0.0, label_shift = 0.75) graphs = [] displacement = 3.0 for i in range(2): graphs.append( main.copy(i * displacement, 0.0) ) graphs[-1].rotate(i * 45.0) main.connect('A', 'B', name = '1', ll = 'bottom', la = 0.0, label_shift = -0.75) for i in range(2): graphs.append( main.copy(i * displacement, 2.0) ) graphs[-1].rotate(i * 45.0) CAN = Canvas(border_thickness = 0.05, grid = True) for graph in graphs: CAN.add_graph(graph)
from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Reflected node labels.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt main = Graph(name = 'main') main.add_node(x=0.0, y=0.0, name = 'A', ll = 'bottom') main.add_node(x=1.0, y=0.0, name = 'B', ll = 'right') main.add_node(x=1.0, y=1.0, name = 'C', ll = 'top') main.add_node(x=0.0, y=1.0, name = 'D', ll = 'left') # BOTTOM bottom = Graph(name = 'bottom') bottom.add_node(x=0.5, y=-1.0, name = 'angled name [x]', ll = 'bottom', la = 45.0) bottom.add_node(x=0.5, y=-1.0, name = 'angled (ref) [x]', ll = 'bottom', la = 45.0, ref = 'x') bottom.add_node(x=0.5, y=-2.0, name = 'angled name [y]', ll = 'bottom', la = 45.0) bottom.add_node(x=0.5, y=-2.0,
from __future__ import print_function from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Pentagon graph test case.') command_line_parser.parse() from schematics import Graph from schematics import Canvas GRAPH = Graph(name='pentagon') # Add Nodes GRAPH.add_node(x=0.0, y=0.0, name='A', anchor=True, ll='top') GRAPH.add_node(x=0.75, y=-1.5, name='B', ll='bottom') GRAPH.add_node(x=-1.5, y=-0.75, name='C', ll='left') GRAPH.add_node(x=1.5, y=-0.75, name='D', ll='right') GRAPH.add_node(x=-0.75, y=-1.5, name='E', ll='bottom') # Add Connections GRAPH.connect('A', 'B', name="I", directional=False, ll='top') GRAPH.connect('C', 'A', name="II", ll='top') GRAPH.connect('A', 'D', name="III", ll='top') GRAPH.connect('A', 'E', name="IV", directional=False, ll='top') GRAPH.connect('B', 'C', name="V", directional=False, ll='top') GRAPH.connect('D', 'B', name="VI", ll='bottom') GRAPH.connect('B', 'E', name="VII", ll='bottom') GRAPH.connect('C', 'D', name="VIII", directional=False, ll='top') GRAPH.connect('E', 'C', name="IX", ll='bottom') GRAPH.connect('D', 'E', name="X", directional=False, ll='top')
from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Shifting edge label.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt from math import sqrt main = Graph(name='main') main.add_node(x=0.0, y=0.0, name='A', ll='bottom') main.add_node(x=1.0, y=0.0, name='B', ll='right') main.connect('A', 'B', name='1', ll='top', la=0.0, label_shift=0.75) graphs = [] displacement = 3.0 for i in range(2): graphs.append(main.copy(i * displacement, 0.0)) graphs[-1].rotate(i * 45.0) main.connect('A', 'B', name='1', ll='bottom', la=0.0, label_shift=-0.75) for i in range(2): graphs.append(main.copy(i * displacement, 2.0)) graphs[-1].rotate(i * 45.0) CAN = Canvas(border_thickness=0.05, grid=True) for graph in graphs: CAN.add_graph(graph)
from schematics import ExampleDebugger command_line_parser = ExampleDebugger('A basic junction.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt from math import sqrt component1 = Graph(name='component1') component1.add_node(x=0.0, y=0.0, name='outlet', ll='bottom') component2 = Graph(name='component2') component2.add_node(x=1.0, y=1.0, name='inlet', ll='right') junction = Graph(name='junction') junction.add_node(x=1.0, y=0.0, name='node', ll='bottom', draw=False) system1 = Graph(name='system1', graphs=[component1, component2, junction]) system1.connect('component1:outlet', 'junction:node', dir=False, ll='top') system1.connect('junction:node', 'component2:inlet', dir=True, ll='top') system2 = system1.copy(2.0, 0.0, name='system2') system2.rotate(45.0) # ----- component1 = Graph(name='component1') component1.add_node(x=0.0, y=2.0, name='outlet', ll='bottom') component2 = Graph(name='component2')
from schematics import ExampleDebugger command_line_parser = ExampleDebugger('A basic junction.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt from math import sqrt component1 = Graph(name = 'component1') component1.add_node(x=0.0, y=0.0, name = 'outlet', ll = 'bottom') component2 = Graph(name = 'component2') component2.add_node(x=1.0, y=1.0, name = 'inlet', ll = 'right') junction = Graph(name = 'junction') junction.add_node(x=1.0, y=0.0, name = 'node', ll = 'bottom', draw = False) system1 = Graph(name = 'system1', graphs = [component1, component2, junction]) system1.connect('component1:outlet', 'junction:node', dir = False, ll = 'top') system1.connect('junction:node', 'component2:inlet', dir = True, ll = 'top') system2 = system1.copy(2.0, 0.0, name = 'system2') system2.rotate(45.0) # ----- component1 = Graph(name = 'component1') component1.add_node(x=0.0, y=2.0, name = 'outlet', ll = 'bottom') component2 = Graph(name = 'component2')
from __future__ import print_function from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Pentagon graph test case.') command_line_parser.parse() from schematics import Graph from schematics import Canvas GRAPH = Graph(name = 'pentagon') # Add Nodes GRAPH.add_node(x=0.0, y=0.0, name = 'A', anchor = True, ll = 'top') GRAPH.add_node(x=0.75, y=-1.5, name = 'B', ll = 'bottom') GRAPH.add_node(x=-1.5, y=-0.75, name = 'C', ll = 'left') GRAPH.add_node(x=1.5, y=-0.75, name = 'D', ll = 'right') GRAPH.add_node(x=-0.75, y=-1.5, name = 'E', ll = 'bottom') # Add Connections GRAPH.connect('A', 'B', name = "I", directional = False, ll = 'top') GRAPH.connect('C', 'A', name = "II", ll = 'top') GRAPH.connect('A', 'D', name = "III", ll = 'top') GRAPH.connect('A', 'E', name = "IV", directional = False, ll = 'top') GRAPH.connect('B', 'C', name = "V", directional = False, ll = 'top') GRAPH.connect('D', 'B', name = "VI", ll = 'bottom') GRAPH.connect('B', 'E', name = "VII", ll = 'bottom') GRAPH.connect('C', 'D', name = "VIII", directional = False, ll = 'top') GRAPH.connect('E', 'C', name = "IX", ll = 'bottom') GRAPH.connect('D', 'E', name = "X", directional = False, ll = 'top')
from schematics import ExampleDebugger command_line_parser = ExampleDebugger('A long junction.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt from math import sqrt component1 = Graph(name='component1') component1.add_node(x=0.0, y=0.0, name='outlet', ll='bottom') component2 = Graph(name='component2') component2.add_node(x=2.0, y=1.0, name='inlet', ll='top') junction = Graph(name='junction') junction.add_node(x=1.0, y=0.0, name='node1', ll='bottom', draw=False) junction.add_node(x=1.0, y=1.0, name='node2', ll='top', draw=False) system1 = Graph(name='system1', graphs=[component1, component2, junction]) system1.connect('component1:outlet', 'junction:node1', dir=False, ll='top', ew=0.05) system1.connect('junction:node1', 'junction:node2', dir=False, ll='top', ew=0.05) system1.connect('junction:node2',
from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Labeled node test case.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt main = Graph(name = 'main') main.add_node(x=0.0, y=0.0, ll = 'bottom') main.add_node(x=1.0, y=0.0, ll = 'right') main.add_node(x=1.0, y=1.0, ll = 'top') main.add_node(x=0.0, y=1.0, ll = 'left') main.connect('Node 0', 'Node 1', label_location = 'bottom', label_angle = 30.0) main.connect('Node 1', 'Node 2', label_location = 'top', label_angle = 30.0) main.connect('Node 2', 'Node 3', label_location = 'top', label_angle = 30.0) main.connect('Node 3', 'Node 0', label_location = 'top', label_angle = 30.0) print main.edges GRAPH = Graph(name = 'graph', graphs = [main], node_line_width = 2.0, node_radius = 0.05) GRAPH.anchor_graph() print 'Nodes are anchored:', GRAPH.anchored print GRAPH.general_info(), '\n' print GRAPH CAN = Canvas(border_thickness = 0.05, grid = True) CAN.add_graph(GRAPH)
from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Labeled edge.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt from math import sqrt main = Graph(name = 'main') main.add_node(x=0.0, y=0.0, name = 'A', ll = 'bottom') main.add_node(x=1.0, y=0.0, name = 'B', ll = 'right') main.add_node(x=1.0, y=1.0, name = 'C', ll = 'top') main.add_node(x=0.0, y=1.0, name = 'D', ll = 'left') main.connect('A', 'B', name = '1', ll = 'top', la = 0.0) main.connect('B', 'C', name = '2', ll = 'top', la = 0.0) main.connect('C', 'D', name = '3', ll = 'top', la = 0.0) main.connect('D', 'A', name = '4', ll = 'top', la = 0.0) main.anchor_graph() print 'Nodes are anchored:', main.anchored print main.general_info(), '\n' print main graphs = [] displacement = 3.0 for i in range(2): graphs.append( main.copy(i * displacement, 0.0) )
from __future__ import print_function from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Reflected graph test case.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt from math import sqrt main = Graph(name='main') main.add_node(x=0.0, y=0.0, name='A', ll='bottom') main.add_node(x=1.0, y=0.0, name='B', ll='right') main.add_node(x=1.0, y=1.0, name='C', ll='top') main.add_node(x=0.0, y=1.0, name='D', ll='left') main.connect('A', 'B', name='1', ll='top', la=45.0, lp=1.0) main.connect('B', 'C', name='2', ll='top', la=45.0, lp=1.0) main.connect('C', 'D', name='3', ll='top', la=45.0, lp=1.0) main.connect('D', 'A', name='4', ll='top', la=45.0, lp=1.0) main.anchor_graph() print('Nodes are anchored:', main.anchored) print(main.general_info(), '\n') print(main) graphs = [] graphs.append(main) graphs.append(main.copy(-1.0, 0.0))
class Component(Label, Transformation): stats = {} def _connect_nodes(self): connected_pairs = [] for node0 in self.graph.nodes.keys(): for node1 in self.graph.nodes.keys(): if node0 != node1: pair0 = (node0, node1) pair1 = (node1, node0) if pair0 not in connected_pairs and pair1 not in connected_pairs: connected_pairs.append(pair0) self.graph.connect(node0, node1, directional = False) def __init__(self, center_of_rotation, **kwargs): Component.stats[self.__class__.__name__] += 1 super(Component, self).__init__(center_of_rotation, **kwargs) Transformation.__init__(self, center_of_rotation, **kwargs) self.name = process_name(None, kwargs) self.label_string = self.name self.graph = Graph(name = self.name) self._get_nodes() self._connect_nodes() self.face_color = process_face_color((1.0, 1.0, 1.0), kwargs) self.edge_color = process_edge_color((0.0, 0.0, 0.0), kwargs) self.line_width = process_line_width(1.5, kwargs) self.patch = None self._points = [] self._connections = [] def _get_path_data(self): Path = mpath.Path self._path_data = [(Path.MOVETO, self._points[0].to_tuple())] point_index = 0 last_point_index = len(self._points) - 1 last_connection_index = len(self._connections) - 1 for connection_index, connection in enumerate(self._connections): connection = connection.lower() # Line if connection == 'lineto': point_index += 1 if point_index <= last_point_index: self._path_data.append( (Path.LINETO, self._points[point_index].to_tuple()) ) elif connection_index == last_connection_index: self._path_data.append( (Path.LINETO, self._points[0].to_tuple()) ) else: sys.exit("Error: Incorrect point and connection specification in custom" + "shape component " + self.__class__.__name__ + ". Ran out of " + "points before all connections could be made.") # Quadratic Bezier Curve elif connection == 'curve3': for i in range(2): point_index += 1 if point_index <= last_point_index: self._path_data.append( (Path.CURVE4, self._points[point_index].to_tuple()) ) elif (connection_index == last_connection_index) and (i == 1): self._path_data.append( (Path.CURVE4, self._points[0].to_tuple()) ) else: sys.exit("Error: Incorrect point and connection specification in custom" + "shape component " + self.__class__.__name__ + ". Ran out of " + "points before all connections could be made.") # Cubic Bezier Curve elif connection == 'curve4': for i in range(3): point_index += 1 if point_index <= last_point_index: self._path_data.append( (Path.CURVE4, self._points[point_index].to_tuple()) ) elif (connection_index == last_connection_index) and (i == 2): self._path_data.append( (Path.CURVE4, self._points[0].to_tuple()) ) else: sys.exit("Error: Incorrect point and connection specification in custom" + "shape component " + self.__class__.__name__ + ". Ran out of " + "points before all connections could be made.") else: sys.exit("Error: Invalid connection specification in custom shape component " + self.__class__.__name__ + ".") if connection_index == last_connection_index: if point_index != len(self._points): sys.exit("Error: Incorrect point and connection specification in custom" + "shape component " + self.__class__.__name__ + ". Too many points " + "specified for the connection types.") self._path_data.append( (Path.CLOSEPOLY, self._points[0].to_tuple()) ) def move(self, x, y): self.center_of_rotation.x = x self.center_of_rotation.y = y def _get_shape(self): for point in self._points: self._reflect(point) self._rotate(point) self._get_path_data() self._codes, self._verts = zip(*self._path_data) self.path = mpath.Path(self._verts, self._codes) def draw_component(self): self._get_shape() self.graph.move(self.center_of_rotation.x, self.center_of_rotation.y) self.graph.reflect(self.reflect) self.graph.rotate(self.angle) self.patches = [mpatches.PathPatch(self.path, facecolor = self.face_color, edgecolor = self.edge_color, linewidth = self.line_width)] return self.patches # Error messages def _get_nodes(self): sys.exit('Error: Must define "_get_nodes" method in the ' + self.__class__.__name__ + ' class.')
from __future__ import print_function from schematics import ExampleDebugger command_line_parser = ExampleDebugger("Reflected graph test case.") command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt from math import sqrt main = Graph(name="main") main.add_node(x=0.0, y=0.0, name="A", ll="bottom") main.add_node(x=1.0, y=0.0, name="B", ll="right") main.add_node(x=1.0, y=1.0, name="C", ll="top") main.add_node(x=0.0, y=1.0, name="D", ll="left") main.connect("A", "B", name="1", ll="top", la=45.0, lp=1.0) main.connect("B", "C", name="2", ll="top", la=45.0, lp=1.0) main.connect("C", "D", name="3", ll="top", la=45.0, lp=1.0) main.connect("D", "A", name="4", ll="top", la=45.0, lp=1.0) main.anchor_graph() print("Nodes are anchored:", main.anchored) print(main.general_info(), "\n") print(main) graphs = [] graphs.append(main)
from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Detailed node label.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt main = Graph(name='main') main.add_node(x=0.0, y=0.0, name='test0', ll='bottom', lp=0.0) main.add_node(x=0.0, y=0.0, name='test1', ll='top', lp=0.0) main.add_node(x=0.0, y=0.0, name='test2', ll='left', lp=0.0) main.add_node(x=0.0, y=0.0, name='test3', ll='right', lp=0.0) bounding = Graph(name='bounding') disp = 0.1 bounding.add_node(x=disp, y=0.0, name='top', dl=False) bounding.add_node(x=-disp, y=0.0, name='bottom', dl=False) bounding.add_node(x=0.0, y=-disp, name='left', dl=False) bounding.add_node(x=0.0, y=disp, name='right', dl=False) GRAPH = Graph(name='graph', graphs=[main, bounding]) CAN = Canvas(border_thickness=0.0, grid=True) CAN.add_graph(GRAPH) CAN.draw(save_file='test.pdf', display=True, print_information=False)
def test_copying_with_subgraphing(self): original_numbers = self._get_original_numbers() pipe1 = Graph(name = 'pipe1') pipe1.add_node(x=0.0, y=0.0, name = 'inlet') pipe1.add_node(1.0, 0.0, name = 'outlet') pipe2 = pipe1.copy(x=1.5, y=0.0, name = 'pipe2') long_pipe1 = Graph(name = 'long_pipe1', graphs = [pipe1, pipe2]) long_pipe1.connect('pipe1:outlet', 'pipe2:inlet', name = "junction") long_pipe1.connect('pipe1:inlet', 'pipe1:outlet', name = "internal-connection1", directional = False) long_pipe1.connect('pipe2:inlet', 'pipe2:outlet', name = "internal-connection2", directional = False) long_pipe2 = long_pipe1.copy(x=2.5, y=1.0, name = 'long_pipe2') long_pipe2.reflect(axis = 'y') circuit = Graph(name = 'circuit', graphs = [long_pipe1, long_pipe2]) circuit.connect('long_pipe1:pipe2:outlet', 'long_pipe2:pipe1:inlet', name = "junction1") circuit.connect('long_pipe2:pipe2:outlet', 'long_pipe1:pipe1:inlet', name = "junction2") nodes = [('long_pipe1:pipe1:inlet', Node(0.0, 0.0)), ('long_pipe1:pipe1:outlet', Node(1.0, 0.0)), ('long_pipe1:pipe2:inlet', Node(1.5, 0.0)), ('long_pipe1:pipe2:outlet', Node(2.5, 0.0)), ('long_pipe2:pipe1:inlet', Node(2.5, 1.0)), ('long_pipe2:pipe1:outlet', Node(1.5, 1.0)), ('long_pipe2:pipe2:inlet', Node(1.0, 1.0)), ('long_pipe2:pipe2:outlet', Node(0.0, 1.0))] edges = [('long_pipe1:junction', Edge('long_pipe1:pipe1:outlet', 'long_pipe1:pipe2:inlet', directional = True)), ('long_pipe1:internal-connection1', Edge('long_pipe1:pipe1:inlet', 'long_pipe1:pipe1:outlet', directional = False)), ('long_pipe1:internal-connection2', Edge('long_pipe1:pipe2:inlet', 'long_pipe1:pipe2:outlet', directional = False)), ('long_pipe2:junction', Edge('long_pipe2:pipe1:outlet', 'long_pipe2:pipe2:inlet', directional = True)), ('long_pipe2:internal-connection1', Edge('long_pipe2:pipe1:inlet', 'long_pipe2:pipe1:outlet', directional = False)), ('long_pipe2:internal-connection2', Edge('long_pipe2:pipe2:inlet', 'long_pipe2:pipe2:outlet', directional = False)), ('junction1', Edge('long_pipe1:pipe2:outlet', 'long_pipe2:pipe1:inlet', directional = True)), ('junction2', Edge('long_pipe2:pipe2:outlet', 'long_pipe1:pipe1:inlet', directional = True))] numbers = (8, # anchored_nodes 8, # anchored_edges 0, # unique_nodes 2, # unique_anchored_edges 0, # unique_unanchored_edges 2, # subgraphs 2 # anchored_subgraphs ) self._check_graph(circuit, 'circuit', 'long_pipe1:pipe1:inlet', True, nodes, edges, numbers) self._check_numbers(original_numbers, 16, 16, 7)
class System(object): subsystems = [] def __init__(self, name, systems = []): self.name = name self.graph = Graph(name = name) self.subsystems = systems self.unique_edges = [] self.junctions = [] self.connections = [] self.connections_kwargs = [] self.components = [] def add_component(self, component): # supress component graph drawing for node in component.graph.nodes.values(): node.draw_bool = False node.draw_label_bool = False for edge in component.graph.edges.values(): edge.draw_bool = False edge.draw_label_bool = False self.graph.add_graph(component.graph) self.components.append(component) def add_node(self, x, y, **kwargs): name = self.graph.add_node(x, y, **kwargs) self.graph.nodes[name].draw_bool = False self.graph.nodes[name].draw_label_bool = False def _already_existing_edge(self, nodeA, nodeB): tmp_edge = Edge(nodeA, nodeB) for edge in self.unique_edges: if tmp_edge == self.graph.edges[edge]: return edge return None def connect(self, *nodes, **kwargs): self.connections.append(nodes) self.connections_kwargs.append(kwargs) number_of_nodes = len(nodes) iterations = number_of_nodes - 1 last_iteration = iterations - 1 junction_edges = [] for i in range(iterations): name = self._already_existing_edge(nodes[i], nodes[i+1]) if name is None: if i == last_iteration: name = self.graph.connect(nodes[i], nodes[i+1], directional = True, draw_label = False) else: name = self.graph.connect(nodes[i], nodes[i+1], directional = False, draw_label = False) self.unique_edges.append(name) junction_edges.append(name) self.junctions.append( Junction(junction_edges, **kwargs) ) def move(self, x, y): displacement = Node(x, y) - self.graph.nodes[self.graph.anchor] for node in self.graph.unique_nodes: self.graph.nodes[node].x += displacement.x self.graph.nodes[node].y += displacement.y for component in self.components: new_coords = component.center_of_rotation + displacement component.move(new_coords.x, new_coords.y) def copy(self, x=0.0, y=0.0, **kwargs): name = process_name(self.name + '(copy)', kwargs) duplicate = System(name, systems = self.subsystems) for component in self.components: duplicate.add_component(deepcopy(component)) for name in self.graph.unique_nodes: duplicate.add_node(self.graph.nodes[name].x, self.graph.nodes[name].y, name = name) for connection, kwargs in zip(self.connections, self.connections_kwargs): duplicate.connect(*connection, **kwargs) duplicate.move(x, y) return duplicate
from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Detailed node label.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt main = Graph(name = 'main') main.add_node(x=0.0, y=0.0, name = 'test0', ll = 'bottom', lp = 0.0) main.add_node(x=0.0, y=0.0, name = 'test1', ll = 'top', lp = 0.0) main.add_node(x=0.0, y=0.0, name = 'test2', ll = 'left', lp = 0.0) main.add_node(x=0.0, y=0.0, name = 'test3', ll = 'right', lp = 0.0) bounding = Graph(name = 'bounding') disp = 0.1 bounding.add_node(x=disp, y=0.0, name = 'top', dl = False) bounding.add_node(x=-disp, y=0.0, name = 'bottom', dl = False) bounding.add_node(x=0.0, y=-disp, name = 'left', dl = False) bounding.add_node(x=0.0, y=disp, name = 'right', dl = False) GRAPH = Graph(name = 'graph', graphs = [main, bounding]) CAN = Canvas(border_thickness = 0.0, grid = True) CAN.add_graph(GRAPH) CAN.draw(save_file = 'test.pdf', display = True, print_information = False)
from __future__ import print_function from schematics import ExampleDebugger command_line_parser = ExampleDebugger('Reflected node labels.') command_line_parser.parse() from schematics import Graph from schematics import Canvas import matplotlib.pyplot as plt main = Graph(name='main') main.add_node(x=0.0, y=0.0, name='A', ll='bottom') main.add_node(x=1.0, y=0.0, name='B', ll='right') main.add_node(x=1.0, y=1.0, name='C', ll='top') main.add_node(x=0.0, y=1.0, name='D', ll='left') # BOTTOM bottom = Graph(name='bottom') bottom.add_node(x=0.5, y=-1.0, name='angled name [x]', ll='bottom', la=45.0) bottom.add_node(x=0.5, y=-1.0, name='angled (ref) [x]', ll='bottom', la=45.0, ref='x') bottom.add_node(x=0.5, y=-2.0, name='angled name [y]', ll='bottom', la=45.0) bottom.add_node(x=0.5,