ugmSorcero commited on
Commit
8de7c36
1 Parent(s): dd7488f
Files changed (2) hide show
  1. interface/draw_pipelines.py +114 -55
  2. 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(start, end, edge_x, edge_y, lengthFrac=1, arrowPos = None, arrowLength=0.025, arrowAngle = 30, dotSize=20):
 
 
 
 
 
 
 
 
 
 
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( (x1-x0)**2 + (y1-y0)**2 )
23
- dotSizeConversion = .0565/20 # length units per dot size
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(None) # Prevents a line being drawn from end of this edge to start of next edge
 
 
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 == 'middle' or arrowPos == 'mid':
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 #verify this once
59
- signy = (y1-y0)/abs(y1-y0) if y1!=y0 else +1 #verified
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
- def add_arrows(source_x: List[float], target_x: List[float], source_y: List[float], target_y: List[float],
85
- arrowLength=0.025, arrowAngle=30):
 
 
 
 
 
 
 
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(map(lambda x: math.degrees(math.atan((x[1] - x[0]) / (x[3] - x[2]))),
89
- zip(source_x, target_x, source_y, target_y)))
90
-
91
- signx = list(map(lambda x: (x[1] - x[0]) / abs(x[1] - x[0]), zip(source_x, target_x)))
92
- signy = list(map(lambda x: (x[1] - x[0]) / abs(x[1] - x[0]), zip(source_y, target_y)))
 
 
 
 
 
 
 
 
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(map(lambda x: x[0] - x[1] ** 2 * x[2] * x[3], zip(pointx, signx, signy, dx)))
98
- arrow_line_y = list(map(lambda x: x[0] - x[1] ** 2 * x[2] * x[3], zip(pointy, signx, signy, dy)))
 
 
 
 
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(map(lambda x: x[0] - x[1] ** 2 * x[2] * x[3], zip(pointx, signx, signy, dx)))
107
- arrow_line_y = list(map(lambda x: x[0] - x[1] ** 2 * x[2] * x[3], zip(pointy, signx, signy, dy)))
 
 
 
 
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 = 'Blue'
121
  nodeSize = 20
122
  lineWidth = 2
123
- lineColor = '#000000'
124
 
125
  G = pipeline.graph
126
 
127
  pos = nx.spring_layout(G)
128
 
129
  for node in G.nodes:
130
- G.nodes[node]['pos'] = list(pos[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]['pos']
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]]['pos']
145
- end = G.nodes[edge[1]]['pos']
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(start, end, edge_x, edge_y, lengthFrac=.8, arrowPos='end', arrowLength=.04, arrowAngle=30, dotSize=nodeSize)
148
-
149
-
150
- edge_trace = go.Scatter(x=edge_x, y=edge_y, line=dict(width=lineWidth, color=lineColor), hoverinfo='none', mode='lines')
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(yaxis = dict(scaleanchor = "x", scaleratio = 1), plot_bgcolor='rgb(255,255,255)')
166
-
167
- return fig
 
 
 
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