Spaces:
Runtime error
Runtime error
ugmSorcero
commited on
Commit
•
8de7c36
1
Parent(s):
dd7488f
Linter
Browse files- interface/draw_pipelines.py +114 -55
- interface/utils.py +2 -1
interface/draw_pipelines.py
CHANGED
@@ -12,31 +12,43 @@ import streamlit as st
|
|
12 |
# arrowLength is the length of the arrowhead
|
13 |
# arrowAngle is the angle in degrees that the arrowhead makes with the edge
|
14 |
# dotSize is the plotly scatter dot size you are using (used to even out line spacing when you have a mix of edge lengths)
|
15 |
-
def addEdge(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
# Get start and end cartesian coordinates
|
18 |
x0, y0 = start
|
19 |
x1, y1 = end
|
20 |
|
21 |
# Incorporate the fraction of this segment covered by a dot into total reduction
|
22 |
-
length = math.sqrt(
|
23 |
-
dotSizeConversion = .0565/20
|
24 |
convertedDotDiameter = dotSize * dotSizeConversion
|
25 |
lengthFracReduction = convertedDotDiameter / length
|
26 |
lengthFrac = lengthFrac - lengthFracReduction
|
27 |
|
28 |
# If the line segment should not cover the entire distance, get actual start and end coords
|
29 |
-
skipX = (x1-x0)*(1-lengthFrac)
|
30 |
-
skipY = (y1-y0)*(1-lengthFrac)
|
31 |
-
x0 = x0 + skipX/2
|
32 |
-
x1 = x1 - skipX/2
|
33 |
-
y0 = y0 + skipY/2
|
34 |
-
y1 = y1 - skipY/2
|
35 |
|
36 |
# Append line corresponding to the edge
|
37 |
edge_x.append(x0)
|
38 |
edge_x.append(x1)
|
39 |
-
edge_x.append(
|
|
|
|
|
40 |
edge_y.append(y0)
|
41 |
edge_y.append(y1)
|
42 |
edge_y.append(None)
|
@@ -48,15 +60,15 @@ def addEdge(start, end, edge_x, edge_y, lengthFrac=1, arrowPos = None, arrowLeng
|
|
48 |
pointx = x1
|
49 |
pointy = y1
|
50 |
|
51 |
-
eta = math.degrees(math.atan((x1-x0)/(y1-y0))) if y1!=y0 else 90.0
|
52 |
|
53 |
-
if arrowPos ==
|
54 |
-
pointx = x0 + (x1-x0)/2
|
55 |
-
pointy = y0 + (y1-y0)/2
|
56 |
|
57 |
# Find the directions the arrows are pointing
|
58 |
-
signx = (x1-x0)/abs(x1-x0) if x1!=x0 else +1
|
59 |
-
signy = (y1-y0)/abs(y1-y0) if y1!=y0 else +1
|
60 |
|
61 |
# Append first arrowhead
|
62 |
dx = arrowLength * math.sin(math.radians(eta + arrowAngle))
|
@@ -78,24 +90,42 @@ def addEdge(start, end, edge_x, edge_y, lengthFrac=1, arrowPos = None, arrowLeng
|
|
78 |
edge_y.append(pointy - signx**2 * signy * dy)
|
79 |
edge_y.append(None)
|
80 |
|
81 |
-
|
82 |
return edge_x, edge_y
|
83 |
|
84 |
-
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
pointx = list(map(lambda x: x[0] + (x[1] - x[0]) / 2, zip(source_x, target_x)))
|
87 |
pointy = list(map(lambda x: x[0] + (x[1] - x[0]) / 2, zip(source_y, target_y)))
|
88 |
-
etas = list(
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
|
94 |
dx = list(map(lambda x: arrowLength * math.sin(math.radians(x + arrowAngle)), etas))
|
95 |
dy = list(map(lambda x: arrowLength * math.cos(math.radians(x + arrowAngle)), etas))
|
96 |
none_spacer = [None for _ in range(len(pointx))]
|
97 |
-
arrow_line_x = list(
|
98 |
-
|
|
|
|
|
|
|
|
|
99 |
|
100 |
arrow_line_1x_coords = list(chain(*zip(pointx, arrow_line_x, none_spacer)))
|
101 |
arrow_line_1y_coords = list(chain(*zip(pointy, arrow_line_y, none_spacer)))
|
@@ -103,8 +133,12 @@ def add_arrows(source_x: List[float], target_x: List[float], source_y: List[floa
|
|
103 |
dx = list(map(lambda x: arrowLength * math.sin(math.radians(x - arrowAngle)), etas))
|
104 |
dy = list(map(lambda x: arrowLength * math.cos(math.radians(x - arrowAngle)), etas))
|
105 |
none_spacer = [None for _ in range(len(pointx))]
|
106 |
-
arrow_line_x = list(
|
107 |
-
|
|
|
|
|
|
|
|
|
108 |
|
109 |
arrow_line_2x_coords = list(chain(*zip(pointx, arrow_line_x, none_spacer)))
|
110 |
arrow_line_2y_coords = list(chain(*zip(pointy, arrow_line_y, none_spacer)))
|
@@ -114,54 +148,79 @@ def add_arrows(source_x: List[float], target_x: List[float], source_y: List[floa
|
|
114 |
|
115 |
return x_arrows, y_arrows
|
116 |
|
|
|
117 |
@st.cache(allow_output_mutation=True)
|
118 |
def get_pipeline_graph(pipeline):
|
119 |
# Controls for how the graph is drawn
|
120 |
-
nodeColor =
|
121 |
nodeSize = 20
|
122 |
lineWidth = 2
|
123 |
-
lineColor =
|
124 |
|
125 |
G = pipeline.graph
|
126 |
|
127 |
pos = nx.spring_layout(G)
|
128 |
|
129 |
for node in G.nodes:
|
130 |
-
G.nodes[node][
|
131 |
-
|
132 |
# Make list of nodes for plotly
|
133 |
node_x = []
|
134 |
node_y = []
|
135 |
for node in G.nodes():
|
136 |
-
x, y = G.nodes[node][
|
137 |
node_x.append(x)
|
138 |
node_y.append(y)
|
139 |
-
|
140 |
# Make a list of edges for plotly, including line segments that result in arrowheads
|
141 |
edge_x = []
|
142 |
edge_y = []
|
143 |
for edge in G.edges():
|
144 |
-
start = G.nodes[edge[0]][
|
145 |
-
end = G.nodes[edge[1]][
|
146 |
# addEdge(start, end, edge_x, edge_y, lengthFrac=1, arrowPos = None, arrowLength=0.025, arrowAngle = 30, dotSize=20)
|
147 |
-
edge_x, edge_y = addEdge(
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
|
153 |
-
node_trace = go.Scatter(x=node_x, y=node_y, mode='markers', hoverinfo='text', marker=dict(showscale=False, color = nodeColor, size=nodeSize))
|
154 |
-
|
155 |
-
fig = go.Figure(data=[edge_trace, node_trace],
|
156 |
-
layout=go.Layout(
|
157 |
-
showlegend=False,
|
158 |
-
hovermode='closest',
|
159 |
-
margin=dict(b=20,l=5,r=5,t=40),
|
160 |
-
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
|
161 |
-
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False))
|
162 |
-
)
|
163 |
-
|
164 |
# Note: if you don't use fixed ratio axes, the arrows won't be symmetrical
|
165 |
-
fig.update_layout(
|
166 |
-
|
167 |
-
|
|
|
|
|
|
12 |
# arrowLength is the length of the arrowhead
|
13 |
# arrowAngle is the angle in degrees that the arrowhead makes with the edge
|
14 |
# dotSize is the plotly scatter dot size you are using (used to even out line spacing when you have a mix of edge lengths)
|
15 |
+
def addEdge(
|
16 |
+
start,
|
17 |
+
end,
|
18 |
+
edge_x,
|
19 |
+
edge_y,
|
20 |
+
lengthFrac=1,
|
21 |
+
arrowPos=None,
|
22 |
+
arrowLength=0.025,
|
23 |
+
arrowAngle=30,
|
24 |
+
dotSize=20,
|
25 |
+
):
|
26 |
|
27 |
# Get start and end cartesian coordinates
|
28 |
x0, y0 = start
|
29 |
x1, y1 = end
|
30 |
|
31 |
# Incorporate the fraction of this segment covered by a dot into total reduction
|
32 |
+
length = math.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2)
|
33 |
+
dotSizeConversion = 0.0565 / 20 # length units per dot size
|
34 |
convertedDotDiameter = dotSize * dotSizeConversion
|
35 |
lengthFracReduction = convertedDotDiameter / length
|
36 |
lengthFrac = lengthFrac - lengthFracReduction
|
37 |
|
38 |
# If the line segment should not cover the entire distance, get actual start and end coords
|
39 |
+
skipX = (x1 - x0) * (1 - lengthFrac)
|
40 |
+
skipY = (y1 - y0) * (1 - lengthFrac)
|
41 |
+
x0 = x0 + skipX / 2
|
42 |
+
x1 = x1 - skipX / 2
|
43 |
+
y0 = y0 + skipY / 2
|
44 |
+
y1 = y1 - skipY / 2
|
45 |
|
46 |
# Append line corresponding to the edge
|
47 |
edge_x.append(x0)
|
48 |
edge_x.append(x1)
|
49 |
+
edge_x.append(
|
50 |
+
None
|
51 |
+
) # Prevents a line being drawn from end of this edge to start of next edge
|
52 |
edge_y.append(y0)
|
53 |
edge_y.append(y1)
|
54 |
edge_y.append(None)
|
|
|
60 |
pointx = x1
|
61 |
pointy = y1
|
62 |
|
63 |
+
eta = math.degrees(math.atan((x1 - x0) / (y1 - y0))) if y1 != y0 else 90.0
|
64 |
|
65 |
+
if arrowPos == "middle" or arrowPos == "mid":
|
66 |
+
pointx = x0 + (x1 - x0) / 2
|
67 |
+
pointy = y0 + (y1 - y0) / 2
|
68 |
|
69 |
# Find the directions the arrows are pointing
|
70 |
+
signx = (x1 - x0) / abs(x1 - x0) if x1 != x0 else +1 # verify this once
|
71 |
+
signy = (y1 - y0) / abs(y1 - y0) if y1 != y0 else +1 # verified
|
72 |
|
73 |
# Append first arrowhead
|
74 |
dx = arrowLength * math.sin(math.radians(eta + arrowAngle))
|
|
|
90 |
edge_y.append(pointy - signx**2 * signy * dy)
|
91 |
edge_y.append(None)
|
92 |
|
|
|
93 |
return edge_x, edge_y
|
94 |
|
95 |
+
|
96 |
+
def add_arrows(
|
97 |
+
source_x: List[float],
|
98 |
+
target_x: List[float],
|
99 |
+
source_y: List[float],
|
100 |
+
target_y: List[float],
|
101 |
+
arrowLength=0.025,
|
102 |
+
arrowAngle=30,
|
103 |
+
):
|
104 |
pointx = list(map(lambda x: x[0] + (x[1] - x[0]) / 2, zip(source_x, target_x)))
|
105 |
pointy = list(map(lambda x: x[0] + (x[1] - x[0]) / 2, zip(source_y, target_y)))
|
106 |
+
etas = list(
|
107 |
+
map(
|
108 |
+
lambda x: math.degrees(math.atan((x[1] - x[0]) / (x[3] - x[2]))),
|
109 |
+
zip(source_x, target_x, source_y, target_y),
|
110 |
+
)
|
111 |
+
)
|
112 |
+
|
113 |
+
signx = list(
|
114 |
+
map(lambda x: (x[1] - x[0]) / abs(x[1] - x[0]), zip(source_x, target_x))
|
115 |
+
)
|
116 |
+
signy = list(
|
117 |
+
map(lambda x: (x[1] - x[0]) / abs(x[1] - x[0]), zip(source_y, target_y))
|
118 |
+
)
|
119 |
|
120 |
dx = list(map(lambda x: arrowLength * math.sin(math.radians(x + arrowAngle)), etas))
|
121 |
dy = list(map(lambda x: arrowLength * math.cos(math.radians(x + arrowAngle)), etas))
|
122 |
none_spacer = [None for _ in range(len(pointx))]
|
123 |
+
arrow_line_x = list(
|
124 |
+
map(lambda x: x[0] - x[1] ** 2 * x[2] * x[3], zip(pointx, signx, signy, dx))
|
125 |
+
)
|
126 |
+
arrow_line_y = list(
|
127 |
+
map(lambda x: x[0] - x[1] ** 2 * x[2] * x[3], zip(pointy, signx, signy, dy))
|
128 |
+
)
|
129 |
|
130 |
arrow_line_1x_coords = list(chain(*zip(pointx, arrow_line_x, none_spacer)))
|
131 |
arrow_line_1y_coords = list(chain(*zip(pointy, arrow_line_y, none_spacer)))
|
|
|
133 |
dx = list(map(lambda x: arrowLength * math.sin(math.radians(x - arrowAngle)), etas))
|
134 |
dy = list(map(lambda x: arrowLength * math.cos(math.radians(x - arrowAngle)), etas))
|
135 |
none_spacer = [None for _ in range(len(pointx))]
|
136 |
+
arrow_line_x = list(
|
137 |
+
map(lambda x: x[0] - x[1] ** 2 * x[2] * x[3], zip(pointx, signx, signy, dx))
|
138 |
+
)
|
139 |
+
arrow_line_y = list(
|
140 |
+
map(lambda x: x[0] - x[1] ** 2 * x[2] * x[3], zip(pointy, signx, signy, dy))
|
141 |
+
)
|
142 |
|
143 |
arrow_line_2x_coords = list(chain(*zip(pointx, arrow_line_x, none_spacer)))
|
144 |
arrow_line_2y_coords = list(chain(*zip(pointy, arrow_line_y, none_spacer)))
|
|
|
148 |
|
149 |
return x_arrows, y_arrows
|
150 |
|
151 |
+
|
152 |
@st.cache(allow_output_mutation=True)
|
153 |
def get_pipeline_graph(pipeline):
|
154 |
# Controls for how the graph is drawn
|
155 |
+
nodeColor = "Blue"
|
156 |
nodeSize = 20
|
157 |
lineWidth = 2
|
158 |
+
lineColor = "#000000"
|
159 |
|
160 |
G = pipeline.graph
|
161 |
|
162 |
pos = nx.spring_layout(G)
|
163 |
|
164 |
for node in G.nodes:
|
165 |
+
G.nodes[node]["pos"] = list(pos[node])
|
166 |
+
|
167 |
# Make list of nodes for plotly
|
168 |
node_x = []
|
169 |
node_y = []
|
170 |
for node in G.nodes():
|
171 |
+
x, y = G.nodes[node]["pos"]
|
172 |
node_x.append(x)
|
173 |
node_y.append(y)
|
174 |
+
|
175 |
# Make a list of edges for plotly, including line segments that result in arrowheads
|
176 |
edge_x = []
|
177 |
edge_y = []
|
178 |
for edge in G.edges():
|
179 |
+
start = G.nodes[edge[0]]["pos"]
|
180 |
+
end = G.nodes[edge[1]]["pos"]
|
181 |
# addEdge(start, end, edge_x, edge_y, lengthFrac=1, arrowPos = None, arrowLength=0.025, arrowAngle = 30, dotSize=20)
|
182 |
+
edge_x, edge_y = addEdge(
|
183 |
+
start,
|
184 |
+
end,
|
185 |
+
edge_x,
|
186 |
+
edge_y,
|
187 |
+
lengthFrac=0.8,
|
188 |
+
arrowPos="end",
|
189 |
+
arrowLength=0.04,
|
190 |
+
arrowAngle=30,
|
191 |
+
dotSize=nodeSize,
|
192 |
+
)
|
193 |
+
|
194 |
+
edge_trace = go.Scatter(
|
195 |
+
x=edge_x,
|
196 |
+
y=edge_y,
|
197 |
+
line=dict(width=lineWidth, color=lineColor),
|
198 |
+
hoverinfo="none",
|
199 |
+
mode="lines",
|
200 |
+
)
|
201 |
+
|
202 |
+
node_trace = go.Scatter(
|
203 |
+
x=node_x,
|
204 |
+
y=node_y,
|
205 |
+
mode="markers",
|
206 |
+
hoverinfo="text",
|
207 |
+
marker=dict(showscale=False, color=nodeColor, size=nodeSize),
|
208 |
+
)
|
209 |
+
|
210 |
+
fig = go.Figure(
|
211 |
+
data=[edge_trace, node_trace],
|
212 |
+
layout=go.Layout(
|
213 |
+
showlegend=False,
|
214 |
+
hovermode="closest",
|
215 |
+
margin=dict(b=20, l=5, r=5, t=40),
|
216 |
+
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
|
217 |
+
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
|
218 |
+
),
|
219 |
+
)
|
220 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
# Note: if you don't use fixed ratio axes, the arrows won't be symmetrical
|
222 |
+
fig.update_layout(
|
223 |
+
yaxis=dict(scaleanchor="x", scaleratio=1), plot_bgcolor="rgb(255,255,255)"
|
224 |
+
)
|
225 |
+
|
226 |
+
return fig
|
interface/utils.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
import core.pipelines as pipelines_functions
|
2 |
from inspect import getmembers, isfunction
|
3 |
|
|
|
4 |
def get_pipelines():
|
5 |
pipeline_names, pipeline_funcs = list(
|
6 |
zip(*getmembers(pipelines_functions, isfunction))
|
@@ -8,4 +9,4 @@ def get_pipelines():
|
|
8 |
pipeline_names = [
|
9 |
" ".join([n.capitalize() for n in name.split("_")]) for name in pipeline_names
|
10 |
]
|
11 |
-
return pipeline_names, pipeline_funcs
|
|
|
1 |
import core.pipelines as pipelines_functions
|
2 |
from inspect import getmembers, isfunction
|
3 |
|
4 |
+
|
5 |
def get_pipelines():
|
6 |
pipeline_names, pipeline_funcs = list(
|
7 |
zip(*getmembers(pipelines_functions, isfunction))
|
|
|
9 |
pipeline_names = [
|
10 |
" ".join([n.capitalize() for n in name.split("_")]) for name in pipeline_names
|
11 |
]
|
12 |
+
return pipeline_names, pipeline_funcs
|