From 4b23da4df1f58022d0a8e2f56c821bf7a705619d Mon Sep 17 00:00:00 2001 From: Mattias Ehatamm Date: Mon, 11 Nov 2024 18:12:33 -0500 Subject: [PATCH 1/9] wip --- pyzx/drawing.py | 2 +- tests/test_drawing.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tests/test_drawing.py diff --git a/pyzx/drawing.py b/pyzx/drawing.py index 7c3e81b8..ceb46b96 100644 --- a/pyzx/drawing.py +++ b/pyzx/drawing.py @@ -56,7 +56,7 @@ def draw(g: Union[BaseGraph[VT,ET], Circuit], labels: bool=False, **kwargs) -> A # allow global setting to labels=False # TODO: probably better to make labels Optional[bool] labels = labels or settings.show_labels - + if get_mode() == "shell": return draw_matplotlib(g, labels, **kwargs) elif get_mode() == "browser": diff --git a/tests/test_drawing.py b/tests/test_drawing.py new file mode 100644 index 00000000..b64fc7dd --- /dev/null +++ b/tests/test_drawing.py @@ -0,0 +1,11 @@ +import sys, os; sys.path.append('..') +from pyzx.graph.graph import Graph +from pyzx.drawing import draw +from pyzx.utils import VertexType, EdgeType + + +g = Graph() +v1 = g.add_vertex(VertexType.BOUNDARY) +v2 = g.add_vertex(VertexType.BOUNDARY) +g.add_edge(g.edge(v1, v2)) +draw(g) \ No newline at end of file From 8fecde1d78ec1a6024658f15dffc4805009e71d6 Mon Sep 17 00:00:00 2001 From: mehatamm Date: Mon, 11 Nov 2024 20:10:20 -0500 Subject: [PATCH 2/9] force algorithm wip --- pyzx/drawing.py | 50 +++++++++++++++++++++++++++++++++++++++---- tests/test_drawing.py | 50 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 5 deletions(-) diff --git a/pyzx/drawing.py b/pyzx/drawing.py index ceb46b96..1d215606 100644 --- a/pyzx/drawing.py +++ b/pyzx/drawing.py @@ -56,7 +56,6 @@ def draw(g: Union[BaseGraph[VT,ET], Circuit], labels: bool=False, **kwargs) -> A # allow global setting to labels=False # TODO: probably better to make labels Optional[bool] labels = labels or settings.show_labels - if get_mode() == "shell": return draw_matplotlib(g, labels, **kwargs) elif get_mode() == "browser": @@ -288,13 +287,54 @@ def draw_matplotlib( # library_code += '' # display(HTML(library_code)) +def auto_draw_vertex_locs(g:BaseGraph[VT, ET], x_scale = 1, y_scale = 1): #Force-based graph drawing algorithm given by Eades(1984): + c1 = 2 + c2 = 1 + c3 = 1 + c4 = .1 + v_loc:Dict[VT, Tuple[int, int]] = dict() + for v in g.vertices(): + v_loc[v]=(random.random()*10, 0 if v in g.inputs() else (1 if v in g.outputs() else random.random()*10)) + for i in range(10): #100 iterations of force-based drawing + print(v_loc.values()) + forces:Dict[VT, Tuple[int, int]] = dict() + for v in g.vertices(): + forces[v] = (0, 0) + for v1 in g.vertices(): + diff = (v_loc[v][0]-v_loc[v1][0], v_loc[v][1]-v_loc[v1][1]) + d = math.sqrt(diff[0]*diff[0]+diff[1]*diff[1]) + if g.connected(v1, v): #edge between vertices: apply rule c1*log(d/c2) + force_mag = -c1*math.log(d/c2) #negative force attracts + elif v != v1: #nonadjacent vertices: apply rule -c3/d^2 + force_mag = c3/(d*d) #positive force repels + else: #free body in question, applies no force on itself + force_mag = 0 + v_force = (diff[0]*force_mag*c4, diff[1]*force_mag*c4) + forces[v] = (forces[v][0]+v_force[0], forces[v][1]+v_force[1]) + for v in g.vertices(): #leave y value constant if input or output + v_loc[v]=(v_loc[v][0]+forces[v][0], 0 if v in g.inputs() else (1 if v in g.outputs() else v_loc[v][1]+forces[v][1])) + max_x = max(v[0] for v in v_loc.values()) + min_x = min(v[0] for v in v_loc.values()) + max_y = max(v[1] for v in v_loc.values()) + min_y = min(v[1] for v in v_loc.values()) + #scale_x = x_scale / (max_x - min_x) + #scale_y = y_scale / (max_y - min_y) + scale_x = x_scale + scale_y = y_scale + + v_loc = {k:((v[0]+min_x)*scale_x, (v[1]+min_y)*scale_y) for k, v in v_loc.items()} #rescale + return v_loc + + + def draw_d3( g: Union[BaseGraph[VT,ET], Circuit], labels:bool=False, scale:Optional[FloatInt]=None, auto_hbox:Optional[bool]=None, show_scalar:bool=False, - vdata: List[str]=[] + vdata: List[str]=[], + auto_draw = False ) -> Any: if get_mode() not in ("notebook", "browser"): @@ -325,10 +365,12 @@ def draw_d3( w = (maxrow-minrow + 2) * scale h = (maxqub-minqub + 3) * scale + if(auto_draw): + v_dict = auto_draw_vertex_locs(g, w, h) nodes = [{'name': str(v), - 'x': (g.row(v)-minrow + 1) * scale, - 'y': (g.qubit(v)-minqub + 2) * scale, + 'x': v_dict[v][0] if auto_draw else (g.row(v)-minrow + 1) * scale, + 'y': v_dict[v][1] if auto_draw else (g.qubit(v)-minqub + 2) * scale, 't': g.type(v), 'phase': phase_to_s(g.phase(v), g.type(v)) if g.type(v) != VertexType.Z_BOX else str(get_z_box_label(g, v)), 'ground': g.is_ground(v), diff --git a/tests/test_drawing.py b/tests/test_drawing.py index b64fc7dd..d043c1cc 100644 --- a/tests/test_drawing.py +++ b/tests/test_drawing.py @@ -1,11 +1,59 @@ import sys, os; sys.path.append('..') +import importlib from pyzx.graph.graph import Graph +from pyzx.graph.base import BaseGraph, VT, ET +import random +from typing import * +import math from pyzx.drawing import draw from pyzx.utils import VertexType, EdgeType +def auto_draw_vertex_locs(g:BaseGraph[VT, ET], x_scale = 1, y_scale = 1): #Force-based graph drawing algorithm given by Eades(1984): + c1 = 2 + c2 = 1 + c3 = 1 + c4 = .1 + v_loc:Dict[VT, Tuple[int, int]] = dict() + for v in g.vertices(): + v_loc[v]=(random.random()*10, random.random()*10) + for i in range(10): #100 iterations of force-based drawing + print(v_loc.values()) + forces:Dict[VT, Tuple[int, int]] = dict() + for v in g.vertices(): + forces[v] = (0, 0) + for v1 in g.vertices(): + diff = (v_loc[v][0]-v_loc[v1][0], v_loc[v][1]-v_loc[v1][1]) + d = math.sqrt(diff[0]*diff[0]+diff[1]*diff[1]) + if g.connected(v1, v): #edge between vertices: apply rule c1*log(d/c2) + force_mag = -c1*math.log(d/c2) #negative force attracts + elif v != v1: #nonadjacent vertices: apply rule -c3/d^2 + force_mag = c3/(d*d) #positive force repels + else: #free body in question, applies no force on itself + force_mag = 0 + v_force = (diff[0]*force_mag*c4, diff[1]*force_mag*c4) + forces[v] = (forces[v][0]+v_force[0], forces[v][1]+v_force[1]) + for v in g.vertices(): #leave y value constant if input or output + v_loc[v]=(v_loc[v][0]+forces[v][0], v_loc[v][1]+forces[v][1]) + max_x = max(v[0] for v in v_loc.values()) + min_x = min(v[0] for v in v_loc.values()) + max_y = max(v[1] for v in v_loc.values()) + min_y = min(v[1] for v in v_loc.values()) + #scale_x = x_scale / (max_x - min_x) + #scale_y = y_scale / (max_y - min_y) + #scale_x = x_scale + #scale_y = y_scale + + #v_loc = {k:((v[0]+min_x)*scale_x, (v[1]+min_y)*scale_y) for k, v in v_loc.items()} #rescale + return v_loc + + g = Graph() v1 = g.add_vertex(VertexType.BOUNDARY) v2 = g.add_vertex(VertexType.BOUNDARY) +v3 = g.add_vertex(VertexType.BOUNDARY) g.add_edge(g.edge(v1, v2)) -draw(g) \ No newline at end of file +g.add_edge(g.edge(v2, v3)) +g.add_edge(g.edge(v1, v3)) +#draw(g) +auto_draw_vertex_locs(g, .1, .1) \ No newline at end of file From c3d65f2bcb8aa77fa02badc5246e7913a5a43dd3 Mon Sep 17 00:00:00 2001 From: Mattias Ehatamm Date: Wed, 13 Nov 2024 22:09:07 -0500 Subject: [PATCH 3/9] add force-based alg wip --- pyzx/drawing.py | 80 ++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/pyzx/drawing.py b/pyzx/drawing.py index 1d215606..cb4857ab 100644 --- a/pyzx/drawing.py +++ b/pyzx/drawing.py @@ -286,45 +286,40 @@ def draw_matplotlib( # library_code += f.read() + '\n' # library_code += '' # display(HTML(library_code)) - -def auto_draw_vertex_locs(g:BaseGraph[VT, ET], x_scale = 1, y_scale = 1): #Force-based graph drawing algorithm given by Eades(1984): +def auto_draw_vertex_locs(g:BaseGraph[VT, ET]): #Force-based graph drawing algorithm given by Eades(1984): c1 = 2 c2 = 1 c3 = 1 c4 = .1 v_loc:Dict[VT, Tuple[int, int]] = dict() for v in g.vertices(): - v_loc[v]=(random.random()*10, 0 if v in g.inputs() else (1 if v in g.outputs() else random.random()*10)) - for i in range(10): #100 iterations of force-based drawing - print(v_loc.values()) + v_loc[v]=(random.random()*10, random.random()*10) + for i in range(100): #100 iterations of force-based drawing forces:Dict[VT, Tuple[int, int]] = dict() for v in g.vertices(): forces[v] = (0, 0) for v1 in g.vertices(): - diff = (v_loc[v][0]-v_loc[v1][0], v_loc[v][1]-v_loc[v1][1]) - d = math.sqrt(diff[0]*diff[0]+diff[1]*diff[1]) - if g.connected(v1, v): #edge between vertices: apply rule c1*log(d/c2) - force_mag = -c1*math.log(d/c2) #negative force attracts - elif v != v1: #nonadjacent vertices: apply rule -c3/d^2 - force_mag = c3/(d*d) #positive force repels - else: #free body in question, applies no force on itself - force_mag = 0 - v_force = (diff[0]*force_mag*c4, diff[1]*force_mag*c4) - forces[v] = (forces[v][0]+v_force[0], forces[v][1]+v_force[1]) + if(v!=v1): + diff = (v_loc[v][0]-v_loc[v1][0], v_loc[v][1]-v_loc[v1][1]) + d = math.sqrt(diff[0]*diff[0]+diff[1]*diff[1]) + if g.connected(v1, v): #edge between vertices: apply rule c1*log(d/c2) + force_mag = -c1*math.log(d/c2) #negative force attracts + elif v != v1: #nonadjacent vertices: apply rule -c3/d^2 + force_mag = c3/(d*d) #positive force repels + else: #free body in question, applies no force on itself + raise ValueError("Vertices ended up at same point") + v_force = (diff[0]*force_mag*c4/d, diff[1]*force_mag*c4/d) + forces[v] = (forces[v][0]+v_force[0], forces[v][1]+v_force[1]) for v in g.vertices(): #leave y value constant if input or output - v_loc[v]=(v_loc[v][0]+forces[v][0], 0 if v in g.inputs() else (1 if v in g.outputs() else v_loc[v][1]+forces[v][1])) + v_loc[v]=(v_loc[v][0]+forces[v][0], v_loc[v][1]+forces[v][1]) max_x = max(v[0] for v in v_loc.values()) min_x = min(v[0] for v in v_loc.values()) max_y = max(v[1] for v in v_loc.values()) min_y = min(v[1] for v in v_loc.values()) - #scale_x = x_scale / (max_x - min_x) - #scale_y = y_scale / (max_y - min_y) - scale_x = x_scale - scale_y = y_scale - - v_loc = {k:((v[0]+min_x)*scale_x, (v[1]+min_y)*scale_y) for k, v in v_loc.items()} #rescale - return v_loc + v_loc = {k:(v[0]-min_x, v[1]-min_y) for k, v in v_loc.items()} #dont rescale + #v_loc = {k:((v[0]-min_x)*(x_scale/(max_x-min_x)), (v[1]-min_y)*y_scale/(max_y-min_y)) for k, v in v_loc.items()} #rescale + return v_loc, max_x-min_x, max_y-min_y def draw_d3( @@ -350,27 +345,36 @@ def draw_d3( # use an 8-digit random alphanum instead. graph_id = ''.join(random_graphid.choice(string.ascii_letters + string.digits) for _ in range(8)) - minrow = min([g.row(v) for v in g.vertices()], default=0) - maxrow = max([g.row(v) for v in g.vertices()], default=0) - minqub = min([g.qubit(v) for v in g.vertices()], default=0) - maxqub = max([g.qubit(v) for v in g.vertices()], default=0) + if(auto_draw): + print("hi") + v_dict, w, h = auto_draw_vertex_locs(g) + if scale is None: + scale = 800 / w + if scale > 50: scale = 50 + if scale < 20: scale = 20 + + w = w * scale + h = h * scale + else: + minrow = min([g.row(v) for v in g.vertices()], default=0) + maxrow = max([g.row(v) for v in g.vertices()], default=0) + minqub = min([g.qubit(v) for v in g.vertices()], default=0) + maxqub = max([g.qubit(v) for v in g.vertices()], default=0) - if scale is None: - scale = 800 / (maxrow-minrow + 2) - if scale > 50: scale = 50 - if scale < 20: scale = 20 + if scale is None: + scale = 800 / (maxrow-minrow + 2) + if scale > 50: scale = 50 + if scale < 20: scale = 20 + + w = (maxrow-minrow + 2) * scale + h = (maxqub-minqub + 3) * scale node_size = 0.2 * scale if node_size < 2: node_size = 2 - w = (maxrow-minrow + 2) * scale - h = (maxqub-minqub + 3) * scale - if(auto_draw): - v_dict = auto_draw_vertex_locs(g, w, h) - nodes = [{'name': str(v), - 'x': v_dict[v][0] if auto_draw else (g.row(v)-minrow + 1) * scale, - 'y': v_dict[v][1] if auto_draw else (g.qubit(v)-minqub + 2) * scale, + 'x': v_dict[v][0]*scale if auto_draw else (g.row(v)-minrow + 1) * scale, + 'y': v_dict[v][1]*scale if auto_draw else (g.qubit(v)-minqub + 2) * scale, 't': g.type(v), 'phase': phase_to_s(g.phase(v), g.type(v)) if g.type(v) != VertexType.Z_BOX else str(get_z_box_label(g, v)), 'ground': g.is_ground(v), From caa0884cf6636dc0d73484c93d316a17e0b7c2ec Mon Sep 17 00:00:00 2001 From: Mattias Ehatamm Date: Wed, 13 Nov 2024 22:09:24 -0500 Subject: [PATCH 4/9] remove prints --- pyzx/drawing.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyzx/drawing.py b/pyzx/drawing.py index cb4857ab..0da232f3 100644 --- a/pyzx/drawing.py +++ b/pyzx/drawing.py @@ -346,7 +346,6 @@ def draw_d3( graph_id = ''.join(random_graphid.choice(string.ascii_letters + string.digits) for _ in range(8)) if(auto_draw): - print("hi") v_dict, w, h = auto_draw_vertex_locs(g) if scale is None: scale = 800 / w From ba000ee9602dd88d3c0ce8ba585f89dbfa90d23d Mon Sep 17 00:00:00 2001 From: Mattias Ehatamm Date: Thu, 14 Nov 2024 16:28:31 -0500 Subject: [PATCH 5/9] offset graph towards center --- pyzx/drawing.py | 23 ++++++++--------- tests/test_drawing.py | 59 ------------------------------------------- 2 files changed, 11 insertions(+), 71 deletions(-) delete mode 100644 tests/test_drawing.py diff --git a/pyzx/drawing.py b/pyzx/drawing.py index 0da232f3..066cd300 100644 --- a/pyzx/drawing.py +++ b/pyzx/drawing.py @@ -286,21 +286,22 @@ def draw_matplotlib( # library_code += f.read() + '\n' # library_code += '' # display(HTML(library_code)) + def auto_draw_vertex_locs(g:BaseGraph[VT, ET]): #Force-based graph drawing algorithm given by Eades(1984): - c1 = 2 + c1 = 2 #Sample parameters that work decently well c2 = 1 c3 = 1 c4 = .1 v_loc:Dict[VT, Tuple[int, int]] = dict() for v in g.vertices(): - v_loc[v]=(random.random()*10, random.random()*10) + v_locs[v]=(random.random()*math.sqrt(g.num_vertices()), random.random()*math.sqrt(g.num_vertices())) for i in range(100): #100 iterations of force-based drawing forces:Dict[VT, Tuple[int, int]] = dict() for v in g.vertices(): forces[v] = (0, 0) for v1 in g.vertices(): if(v!=v1): - diff = (v_loc[v][0]-v_loc[v1][0], v_loc[v][1]-v_loc[v1][1]) + diff = (v_locs[v][0]-v_locs[v1][0], v_locs[v][1]-v_locs[v1][1]) d = math.sqrt(diff[0]*diff[0]+diff[1]*diff[1]) if g.connected(v1, v): #edge between vertices: apply rule c1*log(d/c2) force_mag = -c1*math.log(d/c2) #negative force attracts @@ -311,15 +312,13 @@ def auto_draw_vertex_locs(g:BaseGraph[VT, ET]): #Force-based graph drawing algor v_force = (diff[0]*force_mag*c4/d, diff[1]*force_mag*c4/d) forces[v] = (forces[v][0]+v_force[0], forces[v][1]+v_force[1]) for v in g.vertices(): #leave y value constant if input or output - v_loc[v]=(v_loc[v][0]+forces[v][0], v_loc[v][1]+forces[v][1]) + v_locs[v]=(v_locs[v][0]+forces[v][0], v_locs[v][1]+forces[v][1]) max_x = max(v[0] for v in v_loc.values()) min_x = min(v[0] for v in v_loc.values()) max_y = max(v[1] for v in v_loc.values()) min_y = min(v[1] for v in v_loc.values()) - v_loc = {k:(v[0]-min_x, v[1]-min_y) for k, v in v_loc.items()} #dont rescale - - #v_loc = {k:((v[0]-min_x)*(x_scale/(max_x-min_x)), (v[1]-min_y)*y_scale/(max_y-min_y)) for k, v in v_loc.items()} #rescale - return v_loc, max_x-min_x, max_y-min_y + v_locs = {k:(v[0]-min_x, v[1]-min_y) for k, v in v_locs.items()} #translate to origin + return v_locs, max_x-min_x, max_y-min_y def draw_d3( @@ -352,8 +351,8 @@ def draw_d3( if scale > 50: scale = 50 if scale < 20: scale = 20 - w = w * scale - h = h * scale + w = (w+2) * scale + h = (h+3) * scale else: minrow = min([g.row(v) for v in g.vertices()], default=0) maxrow = max([g.row(v) for v in g.vertices()], default=0) @@ -372,8 +371,8 @@ def draw_d3( if node_size < 2: node_size = 2 nodes = [{'name': str(v), - 'x': v_dict[v][0]*scale if auto_draw else (g.row(v)-minrow + 1) * scale, - 'y': v_dict[v][1]*scale if auto_draw else (g.qubit(v)-minqub + 2) * scale, + 'x': (v_dict[v][0]+1)*scale if auto_draw else (g.row(v)-minrow + 1) * scale, + 'y': (v_dict[v][1]+2)*scale if auto_draw else (g.qubit(v)-minqub + 2) * scale, 't': g.type(v), 'phase': phase_to_s(g.phase(v), g.type(v)) if g.type(v) != VertexType.Z_BOX else str(get_z_box_label(g, v)), 'ground': g.is_ground(v), diff --git a/tests/test_drawing.py b/tests/test_drawing.py deleted file mode 100644 index d043c1cc..00000000 --- a/tests/test_drawing.py +++ /dev/null @@ -1,59 +0,0 @@ -import sys, os; sys.path.append('..') -import importlib -from pyzx.graph.graph import Graph -from pyzx.graph.base import BaseGraph, VT, ET -import random -from typing import * -import math -from pyzx.drawing import draw -from pyzx.utils import VertexType, EdgeType - - -def auto_draw_vertex_locs(g:BaseGraph[VT, ET], x_scale = 1, y_scale = 1): #Force-based graph drawing algorithm given by Eades(1984): - c1 = 2 - c2 = 1 - c3 = 1 - c4 = .1 - v_loc:Dict[VT, Tuple[int, int]] = dict() - for v in g.vertices(): - v_loc[v]=(random.random()*10, random.random()*10) - for i in range(10): #100 iterations of force-based drawing - print(v_loc.values()) - forces:Dict[VT, Tuple[int, int]] = dict() - for v in g.vertices(): - forces[v] = (0, 0) - for v1 in g.vertices(): - diff = (v_loc[v][0]-v_loc[v1][0], v_loc[v][1]-v_loc[v1][1]) - d = math.sqrt(diff[0]*diff[0]+diff[1]*diff[1]) - if g.connected(v1, v): #edge between vertices: apply rule c1*log(d/c2) - force_mag = -c1*math.log(d/c2) #negative force attracts - elif v != v1: #nonadjacent vertices: apply rule -c3/d^2 - force_mag = c3/(d*d) #positive force repels - else: #free body in question, applies no force on itself - force_mag = 0 - v_force = (diff[0]*force_mag*c4, diff[1]*force_mag*c4) - forces[v] = (forces[v][0]+v_force[0], forces[v][1]+v_force[1]) - for v in g.vertices(): #leave y value constant if input or output - v_loc[v]=(v_loc[v][0]+forces[v][0], v_loc[v][1]+forces[v][1]) - max_x = max(v[0] for v in v_loc.values()) - min_x = min(v[0] for v in v_loc.values()) - max_y = max(v[1] for v in v_loc.values()) - min_y = min(v[1] for v in v_loc.values()) - #scale_x = x_scale / (max_x - min_x) - #scale_y = y_scale / (max_y - min_y) - #scale_x = x_scale - #scale_y = y_scale - - #v_loc = {k:((v[0]+min_x)*scale_x, (v[1]+min_y)*scale_y) for k, v in v_loc.items()} #rescale - return v_loc - - -g = Graph() -v1 = g.add_vertex(VertexType.BOUNDARY) -v2 = g.add_vertex(VertexType.BOUNDARY) -v3 = g.add_vertex(VertexType.BOUNDARY) -g.add_edge(g.edge(v1, v2)) -g.add_edge(g.edge(v2, v3)) -g.add_edge(g.edge(v1, v3)) -#draw(g) -auto_draw_vertex_locs(g, .1, .1) \ No newline at end of file From e2c0b534c6b28d4e390d50e6adf22c957d4e1dce Mon Sep 17 00:00:00 2001 From: Mattias Ehatamm Date: Fri, 15 Nov 2024 11:50:08 -0500 Subject: [PATCH 6/9] change name to auto_layout, add to docstring for draw_d3 --- pyzx/drawing.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pyzx/drawing.py b/pyzx/drawing.py index 066cd300..ee9b7d60 100644 --- a/pyzx/drawing.py +++ b/pyzx/drawing.py @@ -287,7 +287,7 @@ def draw_matplotlib( # library_code += '' # display(HTML(library_code)) -def auto_draw_vertex_locs(g:BaseGraph[VT, ET]): #Force-based graph drawing algorithm given by Eades(1984): +def auto_layout_vertex_locs(g:BaseGraph[VT, ET]): #Force-based graph drawing algorithm given by Eades(1984): c1 = 2 #Sample parameters that work decently well c2 = 1 c3 = 1 @@ -328,9 +328,10 @@ def draw_d3( auto_hbox:Optional[bool]=None, show_scalar:bool=False, vdata: List[str]=[], - auto_draw = False + auto_layout = False ) -> Any: - + """If auto_layout is checked, will automatically space vertices of graph + with no regard to qubit/row.""" if get_mode() not in ("notebook", "browser"): raise Exception("This method only works when loaded in a webpage or Jupyter notebook") @@ -344,8 +345,8 @@ def draw_d3( # use an 8-digit random alphanum instead. graph_id = ''.join(random_graphid.choice(string.ascii_letters + string.digits) for _ in range(8)) - if(auto_draw): - v_dict, w, h = auto_draw_vertex_locs(g) + if(auto_layout): + v_dict, w, h = auto_layout_vertex_locs(g) if scale is None: scale = 800 / w if scale > 50: scale = 50 From 0eec7d4cb877d8ce1e3932407968d80e87b0540a Mon Sep 17 00:00:00 2001 From: Mattias Ehatamm Date: Fri, 15 Nov 2024 13:17:02 -0500 Subject: [PATCH 7/9] fix typo --- pyzx/drawing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyzx/drawing.py b/pyzx/drawing.py index ee9b7d60..44a14750 100644 --- a/pyzx/drawing.py +++ b/pyzx/drawing.py @@ -292,7 +292,7 @@ def auto_layout_vertex_locs(g:BaseGraph[VT, ET]): #Force-based graph drawing alg c2 = 1 c3 = 1 c4 = .1 - v_loc:Dict[VT, Tuple[int, int]] = dict() + v_locs:Dict[VT, Tuple[int, int]] = dict() for v in g.vertices(): v_locs[v]=(random.random()*math.sqrt(g.num_vertices()), random.random()*math.sqrt(g.num_vertices())) for i in range(100): #100 iterations of force-based drawing From 3152e12012e5827903eaaf2edb057df81c6c9d6a Mon Sep 17 00:00:00 2001 From: Mattias Ehatamm Date: Fri, 15 Nov 2024 13:17:59 -0500 Subject: [PATCH 8/9] fix typos 2 --- pyzx/drawing.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyzx/drawing.py b/pyzx/drawing.py index 44a14750..599158a4 100644 --- a/pyzx/drawing.py +++ b/pyzx/drawing.py @@ -313,10 +313,10 @@ def auto_layout_vertex_locs(g:BaseGraph[VT, ET]): #Force-based graph drawing alg forces[v] = (forces[v][0]+v_force[0], forces[v][1]+v_force[1]) for v in g.vertices(): #leave y value constant if input or output v_locs[v]=(v_locs[v][0]+forces[v][0], v_locs[v][1]+forces[v][1]) - max_x = max(v[0] for v in v_loc.values()) - min_x = min(v[0] for v in v_loc.values()) - max_y = max(v[1] for v in v_loc.values()) - min_y = min(v[1] for v in v_loc.values()) + max_x = max(v[0] for v in v_locs.values()) + min_x = min(v[0] for v in v_locs.values()) + max_y = max(v[1] for v in v_locs.values()) + min_y = min(v[1] for v in v_locs.values()) v_locs = {k:(v[0]-min_x, v[1]-min_y) for k, v in v_locs.items()} #translate to origin return v_locs, max_x-min_x, max_y-min_y @@ -372,8 +372,8 @@ def draw_d3( if node_size < 2: node_size = 2 nodes = [{'name': str(v), - 'x': (v_dict[v][0]+1)*scale if auto_draw else (g.row(v)-minrow + 1) * scale, - 'y': (v_dict[v][1]+2)*scale if auto_draw else (g.qubit(v)-minqub + 2) * scale, + 'x': (v_dict[v][0]+1)*scale if auto_layout else (g.row(v)-minrow + 1) * scale, + 'y': (v_dict[v][1]+2)*scale if auto_layout else (g.qubit(v)-minqub + 2) * scale, 't': g.type(v), 'phase': phase_to_s(g.phase(v), g.type(v)) if g.type(v) != VertexType.Z_BOX else str(get_z_box_label(g, v)), 'ground': g.is_ground(v), From 0f782d539736bc91dbd4e0765a6184c85cea4e20 Mon Sep 17 00:00:00 2001 From: Mattias Ehatamm Date: Fri, 15 Nov 2024 13:24:26 -0500 Subject: [PATCH 9/9] fix typing --- pyzx/drawing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyzx/drawing.py b/pyzx/drawing.py index 599158a4..656e86b4 100644 --- a/pyzx/drawing.py +++ b/pyzx/drawing.py @@ -292,11 +292,11 @@ def auto_layout_vertex_locs(g:BaseGraph[VT, ET]): #Force-based graph drawing alg c2 = 1 c3 = 1 c4 = .1 - v_locs:Dict[VT, Tuple[int, int]] = dict() + v_locs:Dict[VT, Tuple[float, float]] = dict() for v in g.vertices(): v_locs[v]=(random.random()*math.sqrt(g.num_vertices()), random.random()*math.sqrt(g.num_vertices())) for i in range(100): #100 iterations of force-based drawing - forces:Dict[VT, Tuple[int, int]] = dict() + forces:Dict[VT, Tuple[float, float]] = dict() for v in g.vertices(): forces[v] = (0, 0) for v1 in g.vertices():