def gen_heart_array(flag_defs): heart = Clip(gen_heart(), clipid="newid") heart_coords = load_heart_coords() flag_list = [heart.clipper()] coord_list = [] for idx, flag_def in enumerate(flag_defs[:len(heart_coords)]): x = f"{heart_coords[idx]['x']}" y = f"{int(heart_coords[idx]['y'])+50}" flag = Flag(**flag_def) flag_list.append( svg(text(flag.name, y=f"{-20}", **{ 'text-anchor': "middle", "font-family": "Minion Pro", "font-size": "15" }), heart.clip(flag.flag(), ), x=x, y=y, height="100px", viewBox="-25 -25 50 50", style={"overflow": "visible"}, version="1.1", baseProfile="full", xmlns="http://www.w3.org/2000/svg", **{ "xmlns:xlink": "http://www.w3.org/1999/xlink", "xml:space": "preserve" })) heart_array = svg(*flag_list, width=f"{90*8}", viewBox="250 0 675 675", version="1.1", baseProfile="full", xmlns="http://www.w3.org/2000/svg", **{ "xmlns:xlink": "http://www.w3.org/1999/xlink", "xml:space": "preserve" }) return heart_array
def encode(self, **kwargs): myflag = svg(self.flag(**kwargs), viewBox="-25 -25 50 50", version="1.1", baseProfile="full", xmlns="http://www.w3.org/2000/svg", **{ "xmlns:xlink": "http://www.w3.org/1999/xlink", "xml:space": "preserve" }) return myflag.to_html().encode('utf-8')
def encode_heart(flag_def, **kwargs): heart_shape = Clip(gen_heart(), clipid="uniquid") heart = svg(heart_shape.clipper(), heart_shape.clip(Flag(**flag_def).flag()), viewBox="-25 -25 50 50", version="1.1", baseProfile="full", xmlns="http://www.w3.org/2000/svg", **{ "xmlns:xlink": "http://www.w3.org/1999/xlink", "xml:space": "preserve" }) return heart.to_html().encode('utf-8')
def show_clip(self, *targets, edge=False, clip=True, style=None, **kwargs): if style is not None: style = {} outline = self.shapes if edge else [""] to_display = [self.clip(*targets, **kwargs)] if clip else targets return svg(*to_display, *outline, viewBox="-25 -25 50 50", version="1.1", baseProfile="full", xmlns="http://www.w3.org/2000/svg", **{ "xmlns:xlink": "http://www.w3.org/1999/xlink", "xml:space": "preserve" })
def animated_flag_heart(this_flag=None, stroke_color="grey"): # this_flag = flag_dict[this_flag_name] if isinstance(this_flag, str): flag_dict = load_flag_dict() this_flag = flag_dict[this_flag] heart = Clip(gen_heart()) fade_out = gen_fade_out() anim_flag_heart = svg(heart.clipper(), heart.clip(Flag(**this_flag).flag()), group( Flag(**this_flag).flag(**{"id": "myflag"}), animated_heart(stroke_color=stroke_color), fade_out), viewBox="-25 -25 50 50", height="450") return anim_flag_heart
def _repr_mimebundle_(self, include=None, exclude=None): viewer = svg(self.flag(), viewBox="-25 -25 50 50", version="1.1", baseProfile="full", width="300px", height="200px", xmlns="http://www.w3.org/2000/svg", x="0px", y="0px", **{ "xmlns:xlink": "http://www.w3.org/1999/xlink", "xml:space": "preserve" }) return { **viewer._repr_mimebundle_(None, None), "text/html": viewer._repr_html_(), "image/svg+xml": viewer._repr_html_() }
def __repr__(self): ''' Do two passes to find the maximum layer size, and scale everything else based on that. ''' max_input_size = 0 max_linear_size = 0 max_channel_size = 0 max_layer_height = 0 filter_offset_size = 5 for layer in self.trace: if 'Conv' in layer.type: if layer.channels > max_channel_size: max_channel_size = layer.channels if layer.input_shape > max_input_size: max_input_size = layer.input_shape else: # print(layer.input_shape) if layer.input_shape > max_linear_size: max_linear_size = layer.input_shape channel_factor = 1 if max_channel_size == 0 else math.log(max_channel_size) print(channel_factor) layer_offset = 0 vertical_offset = 0 svg_width = 0 svg_height = 500 conv_group = [] annotation_group = [] linear_group = [] linear_layer_width = 50 max_group_height = None last_layer = None last_offset = 0 for layer in self.trace: # print(layer.type, layer.input_shape, layer.output_shape, layer.channels) if layer.type == 'Linear': vertical_offset = 0 padding = 30 max_height = max_group_height if max_group_height is not None else svg_height - 2 * padding rect_height = np.interp(layer.input_shape, [0, max_linear_size], [0, max_height]) effective_width = (math.sin(math.radians(45)) * rect_height) effective_height = (math.cos(math.radians(45)) * rect_height) layer.effective_height = effective_height layer.effective_width = effective_width rect_top = np.interp(rect_height, [0, max_height], [svg_height / 2, (svg_height - max_height) / 2]) layer_offset += min(rect_height / 4, 30) if max_group_height is None: layer_offset += effective_width / 2 if last_layer is not None and 'Linear' in last_layer.type: annotation_group.append(g( line( x1=str(layer_offset - effective_width / 2 + 20), y1=str(svg_height / 2 - effective_height / 2 + 5), x2=str(last_offset - last_layer.effective_width / 2 + 25), y2=str(svg_height / 2 - last_layer.effective_height / 2 + 5), stroke="black", strokeWidth="2" ) )) annotation_group.append(g( line( x1=str(layer_offset + effective_width / 2 + 15), y1=str(svg_height / 2 + effective_height / 2 + 5), x2=str(last_offset + last_layer.effective_width / 2 + 20), y2=str(svg_height / 2 + last_layer.effective_height / 2), stroke="black", strokeWidth="2" ) )) elif last_layer is not None and 'Conv' in last_layer.type: annotation_group.append( line( x1=str(last_offset + last_layer.rect_width), y1=str(last_layer.vertical_offset), x2=str(layer_offset - effective_width / 2 + 20), y2=str(svg_height / 2 - effective_height / 2 + 5), stroke='#222' ) ) annotation_group.append( line( x1=str(last_offset + last_layer.rect_width + (last_layer.channels - 1) * filter_offset_size), y1=str(last_layer.vertical_offset + (last_layer.channels - 1) * filter_offset_size + last_layer.rect_width), x2=str(layer_offset + effective_width / 2 + 15), y2=str(svg_height / 2 + effective_height / 2 + 5), stroke='#222' ) ) linear_group.append(g( [rect( x=str((linear_layer_width - 20) / 2), y=str(rect_top), width='10', height=str(rect_height), fill='#efefef', stroke='#bbb', strokeWidth="3", transform='rotate(-45, ' + str(linear_layer_width / 2) + ', ' + str(svg_height / 2) +')' ), text( str(layer.output_shape), x=str(effective_width / 2 + rect_height / 8), y=str(svg_height / 2 + effective_height / 2 - rect_height / 8), textAnchor="start", fill="black" ), text( str(layer.input_shape), x=str(-effective_width / 2 ), y=str(svg_height / 2 - effective_height / 2 + rect_height / 8), textAnchor="end", fill="black" ) ], transform='translate(' + str(layer_offset) + ', 0)' )) last_offset = layer_offset layer_offset += (effective_width / 2) elif 'Conv' in layer.type: layer._channels = layer.channels layer.channels = round(layer.channels / channel_factor) rect_width = np.interp(layer.input_shape, [0, max_input_size], [min_conv_size, max_conv_size]) group_height = rect_width + filter_offset_size * layer.channels if max_group_height is None or group_height > max_group_height: max_group_height = group_height vertical_offset = np.interp(group_height, [0, svg_height], [svg_height / 2, 0]) layer.vertical_offset = vertical_offset layer.rect_width = rect_width rects = [] # print(group_height) for i in range(layer.channels): rects.append( rect( x=str(i * filter_offset_size), y=str(i * filter_offset_size), width=str(rect_width), height=str(rect_width), fill='#dddddd' if i % 2 == 0 else '#bbbbbb') ) rects.append( rect( x=str((layer.channels - 1) * filter_offset_size + rect_width / 4), y=str((layer.channels - 1) * filter_offset_size + rect_width / 4), width=str(np.interp(layer.kernel_size, [0, max_input_size], [min_conv_size, max_conv_size])), height=str(np.interp(layer.kernel_size, [0, max_input_size], [min_conv_size, max_conv_size])), fill='none', stroke='#222' ) ) rects.append( text( str(layer._channels) + ' @ ' + str(layer.input_shape) + ' X ' + str(layer.input_shape), x=str((rect_width / 2 + layer.channels * filter_offset_size) / 2), y=str(group_height + 40), textAnchor="middle", fill="black" ) ) if last_layer and 'Conv' in last_layer.type: annotation_group.append( line( x1=str(last_offset + (last_layer.channels - 1) * filter_offset_size + last_layer.rect_width / 4 + (np.interp(last_layer.kernel_size, [0, max_input_size], [min_conv_size, max_conv_size]))), y1=str(last_layer.vertical_offset + (last_layer.channels - 1) * filter_offset_size + last_layer.rect_width / 4), x2=str(layer_offset + (layer.channels - 1) * filter_offset_size + rect_width / 2), y2=str(vertical_offset + (layer.channels - 1) * filter_offset_size + rect_width / 2), stroke='#222' ) ) annotation_group.append( line( x1=str(last_offset + (last_layer.channels - 1) * filter_offset_size + last_layer.rect_width / 4 + (np.interp(last_layer.kernel_size, [0, max_input_size], [min_conv_size, max_conv_size]))), y1=str(last_layer.vertical_offset + (last_layer.channels - 1) * filter_offset_size + last_layer.rect_width / 4 + (np.interp(last_layer.kernel_size, [0, max_input_size], [min_conv_size, max_conv_size]))), x2=str(layer_offset + (layer.channels - 1) * filter_offset_size + rect_width / 2), y2=str(vertical_offset + (layer.channels - 1) * filter_offset_size + rect_width / 2), stroke='#222' ) ) conv_group.append(g(rects, transform='translate(' + str(layer_offset) + ', ' + str(vertical_offset) + ')')) last_offset = layer_offset layer_offset += rect_width + layer.channels * filter_offset_size + 20 else: print(layer.type) print('???') continue last_layer = layer groups = g(conv_group + annotation_group + linear_group) display(svg( groups, width=str(1.10 * layer_offset), height=str(svg_height), style={ 'overflow': 'visible', 'max-width': 'none', 'height': 'auto'} )) return ''