def draw(self, x, y): x += self.pad # Relative scale scale = self.size / self.max_size * 0.75 + 0.25 sy = y + draw.height() * (1 - scale) / 2 sx = x if self.simple: w, h = draw.rect(x + 4, sy, 8, draw.height() * scale) else: w, h = 16, draw.height() * scale n_nodes = int(draw.height() * scale / 8) if self.size <= 3: n_nodes = self.size offy = (h - n_nodes * 10) / 2 self.circle_positions = [] for i in range(n_nodes): draw.circle(x + 8, sy + i * 10 + 4 + offy, 4) self.circle_positions.append((x + 8, sy + i * 10 + 4 + offy)) sy += offy h -= offy - 1 sx += 6 x -= 2 if self.label is not None: draw.text(self.label, x + w / 2 + 2, sy + h + 10, center=True) if self.comment is not None: draw.text(self.comment, x + w / 2 + 2, sy + h + 20, center=True, italic=True, color="gray") if self.size_label: draw.text(str(self.size), x + w / 2 + 2, sy - 5, center=True, italic=True, color="gray") # Attachment positions self.top_left = (sx, sy) self.bot_left = (sx, sy + h) self.top_right = (sx + 12, sy) self.bot_right = (sx + 12, sy + h) return w + self.pad * 2
def draw(self, x, y): width = 48 height = 48 sy = y + (draw.height() - height) / 2 draw.rect(x, sy, width, height, fill="#eeeeee") # Label if self.label is not None: draw.text(self.label, x + width / 2, sy + height + 10, center=True) if self.comment is not None: draw.text(self.comment, x + width / 2, sy + height + 20, center=True, italic=True, color="gray") # Attachment positions self.top_right = (x + width, sy) self.top_left = (x, sy) self.bot_left = (x, sy + height) self.bot_right = (x + width, sy + height) return width
def _draw(self, debug=False): # 256 by default, makes everything less than this appear smaller MAX_DENSE_NODES = 256 MAX_CONV_FILTERS = 1 for l in self.elements: if isinstance(l, element.Dense): MAX_DENSE_NODES = max(l.size, MAX_DENSE_NODES) if isinstance(l, element.Conv): MAX_CONV_FILTERS = max(l.size, MAX_CONV_FILTERS) DRAW_X = 0 DRAW_Y = 0 prev = None for l in self.elements: if isinstance(l, element.Padding): DRAW_X += l.width continue # Needs max nodes for relative sizes if isinstance(l, element.Dense): l.max_size = MAX_DENSE_NODES if isinstance(l, element.Conv): l.max_size = MAX_CONV_FILTERS w = l.draw(DRAW_X, DRAW_Y) if debug: draw.text(type(l).__name__, DRAW_X, DRAW_Y - 4, italic=True, color="red") draw.rect(DRAW_X - 1, DRAW_Y - 1, w + 2, draw.height() + 2, stroke="red", fill="none") if prev is not None: prev.attach(l) DRAW_X += w + self.SPACING prev = l if debug: draw.rect(-2, -2, DRAW_X + 4, draw.height() + 4, stroke="blue", fill="none") return DRAW_X
def draw(self, x, y): # Relative scale scale = self.size / self.max_size * 0.25 + 0.75 # Max 16 nodes in figure nodes = int(min(max(20 * scale, 1), 20)) if self.size <= 20: nodes = self.size width = nodes * 4 + 20 height = nodes * 4 + 20 sy = y + (draw.height() - height) / 2 for i in range(nodes): f = "#eeeeee" if not (i + nodes % 2) % 2 else "white" draw.rect(x + i * 4, sy + i * 4, 24, 24, fill=f) # Attachment positions self.top_left = (x, sy) self.top_right = (x + 24, sy) self.bot_left = (x + width - 24, sy + height) self.bot_right = (x + width, sy + height) self.center = (x + width / 2 - 18, sy + height / 2 + 4) # Label if self.label is not None: draw.text(self.label, x + width - 12, sy + height + 10, center=True) # Comment if self.comment is not None: draw.text(self.comment, x + width - 12, sy + height + 20, center=True, italic=True, color="gray") # Size label if self.size_label: # draw.line(x+24+8, sy, x+width, sy+height-24-8, stroke="gray") draw.text(str(self.size), x + width / 2 + 16, sy + height / 2 - 16, italic=True, color="gray") return width
def _draw(self, debug=False): self._width = 0 self._height = 0 GRAPH_POSITIONS = [[(0, 0, 0, 0) for _ in range(10)] for _ in range(10)] for y in range(10): self._step_draw_position = 0 for x in range(10): graph = self._graphs[x][y] # Draw at correct position if graph is None: continue draw.begin(self._figure) gw = graph._draw(debug) # Calculate translation x_translate = self._PADDING + self._H_SPACING * x x_translate += self._step_draw_position y_translate = (draw.height() + self._V_SPACING) * y + self._PADDING / 2 if self.title is not None: y_translate += 30 if self.author is not None: y_translate += 10 # Add to group and translate in figure group = self._figure.g() draw.add_all(group) group.translate(x_translate, y_translate) self._figure.add(group) GRAPH_POSITIONS[x][y] = (x_translate, y_translate, gw) self._step_draw_position += gw self._width = max(self._width, self._step_draw_position + self._PADDING) self._height = max(self._height, y_translate + draw.height() + self._PADDING) self._width += self._PADDING / 4 # Draw connections draw.begin(self._figure) for con in self._connections: x, y, x2, y2, position, offset = con from_x, from_y, from_w = GRAPH_POSITIONS[x][y] to_x, to_y, to_w = GRAPH_POSITIONS[x2][y2] from_x += from_w - 16 from_y += draw.height() / 2 to_y += draw.height() / 2 # First out draw.line(from_x - 16, from_y, from_x + 12, from_y, stroke="gray") # Arrowhead draw.line(to_x - 6, to_y - 5, to_x - 1, to_y, stroke="gray") draw.line(to_x - 6, to_y + 5, to_x - 1, to_y, stroke="gray") if y < y2: mid = to_y - draw.height() / 2 - self._V_SPACING / 2 else: mid = to_y + draw.height() / 2 + self._V_SPACING / 2 if position is not None: mid = (draw.height() + self._V_SPACING ) * position + self._PADDING / 2 - self._V_SPACING / 2 if self.title is not None: mid += 30 if self.author is not None: mid += 10 if offset is not None: mid += offset draw.line(from_x + 12, from_y, from_x + 12, mid, stroke="gray") draw.line(from_x + 12, mid, to_x - 16, mid, stroke="gray") draw.line(to_x - 16, mid, to_x - 16, to_y, stroke="gray") draw.line(to_x - 16, to_y, to_x - 1, to_y, stroke="gray") draw.add_all(self._figure)