def treemap(queue, glyphs): if len(queue) == 0: return node = queue[0] queue.pop(0) if node.children: # squarify the children based on parent coordinates values = list() [values.append(child.data) for child in node.children] values = squarify.normalize_sizes(values, node.dx, node.dy) rects = squarify.padded_squarify(values, node.x, node.y, node.dx, node.dy) # have to save glyph info so we can squarify children for i in range(len(node.children)): node.children[i].x = rects[i]['x'] node.children[i].y = rects[i]['y'] node.children[i].dx = rects[i]['dx'] node.children[i].dy = rects[i]['dy'] rects[i]['label'] = node.children[i].label [queue.append(child) for child in node.children] [glyphs.append(rect) for rect in rects] treemap(queue, glyphs)
def _bbox_squarify(component_sizes, pad_x=10, pad_y=10): """Arrange bounding boxes using the `squarify` implementation for treemaps""" try: import squarify except ImportError: raise ImportError( "Using the 'components layout' requires the installation" "of the `squarify` package. You can install it with " "`pip install squarify`") order = np.argsort(-component_sizes) undo_order = np.argsort(order) component_sizes = component_sizes[order] component_sizes = squarify.normalize_sizes(component_sizes, 100, 100) rects = squarify.padded_squarify(component_sizes, 0, 0, 100, 100) bboxes = [] for r in rects: width = r["dx"] height = r["dy"] offset_x = r["x"] offset_y = r["y"] delta = abs(width - height) if width > height: width = height offset_x += delta / 2 else: height = width offset_y += delta / 2 bboxes.append((offset_x, offset_y, width - pad_x, height - pad_y)) return [bboxes[i] for i in undo_order]
def plot_compostos(lista_compostos): fig = plt.gcf() ax = fig.add_subplot() num_elementos_total = 0 num_elemento_compostos = {} for nome_composto in [x[1] for x in lista_compostos]: composto = drogas_pesadas[nome_composto] num_elemento_compostos[nome_composto] = 0 for elemento in composto: num_elementos_total += composto[elemento] num_elemento_compostos[nome_composto] += composto[elemento] num_elemento_compostos_sorted = sorted([[num_elemento_compostos[val], val] for val in num_elemento_compostos], reverse=True) rects = squarify.padded_squarify( [val for val, key in num_elemento_compostos_sorted], 0, 0, 400, 400) for val, key in num_elemento_compostos_sorted: pass x = [rect['x'] for rect in rects] y = [rect['y'] for rect in rects] dx = [rect['dx'] for rect in rects] dy = [rect['dy'] for rect in rects] colors = [] labels = [] ax.bar(x, dy, width=dx, bottom=y, color=color, label=labels) plt.axis('off') plt.show()
def plotly_treemap(dataframe, groups, subgroups, values, filename = None, colors = None): import pandas as pd import squarify #Create parent squaresizes dataframe = dataframe.sort_values(groups) grp = dataframe.groupby(groups)[values].sum() #Initialize first square x = 0. y = 0. width = 100. height = 100. sizes = grp.values # Parent squares normed = squarify.normalize_sizes(sizes, width, height) rects = squarify.squarify(normed, x, y, width, height) subrects = [] for group, rect in zip(set(dataframe[groups]), rects): dff = dataframe[dataframe[groups] == group][values] x = rect['x'] y = rect['y'] width = rect['dx'] height = rect['dy'] sizes = dff.values normed = squarify.normalize_sizes(sizes, width, height) rectgroup = squarify.padded_squarify(normed, x, y, width, height) subrects += rectgroup return(subrects)
def vals(self, project): if not self.__skip_initial: self.values = [project.get_sloc()] self.valuedetails = [None] self.types = [None] # Classes with clones for cls in project.CLASSES: for cos in cls: __sloc = cos.get_sloc() self.values.append(__sloc) if self.__color_per_clone: self.types.append(cos.get_type()) if not self.__skip_initial: self.values[0] -= __sloc self.valuedetails.append(cos) # self.values.sort(reverse=False) self.colors = self.get_colors(len(self.values)) self.values_normalized = squarify.normalize_sizes( self.values, self.width, self.height) # self.rects = squarify.squarify( # self.values, # self.x, # self.y, # self.width, # self.height # ) # padded rectangles will probably visualize better for certain cases self.padded_rects = squarify.padded_squarify(self.values_normalized, self.x, self.y, self.width, self.height)
def tree_layout(ftp_host, path=''): response.content_type = 'application/json' # get node metadata tree = get_tree(cache[ftp_host]['tree'], path) children = tree['children'].keys() sizes = [tree['children'][child]['size'] for child in children] # filter out zero values children = filter(lambda child: tree['children'][child]['size'] > 0, children) sizes = filter(lambda size: size > 0, sizes) # sort the objects by size, descending order = argsort(sizes)[::-1] children = [children[i] for i in order] sizes = [sizes[i] for i in order] # compute the treemap layout sizes = squarify.normalize_sizes(sizes, width, height) rects = squarify.padded_squarify(sizes, 0, 0, width, height) # annotate rects with some metadata for (child, rect) in zip(children, rects): rect['host'] = ftp_host rect['path'] = os.path.join(path, child) rect['name'] = child rect['size'] = bytes2human(tree['children'][child]['size']) if len(tree['children'][child]['children']) == 0: rect['type'] = 'file' else: rect['type'] = 'dir' # if I am at a leaf node, then rects should be empty # in that case, add a single rectangle for the whole canvas if len(rects) == 0: rects.append({ 'x': 0, 'y': 0, 'dx': width, 'dy': height, 'host': ftp_host, 'path': path, 'name': path.split('/')[-1], 'size': bytes2human(tree['size']), 'type': 'file' }) data = {} data['rects'] = rects data['size'] = tree['size'] data['humansize'] = bytes2human(tree['size']) data['date'] = cache[ftp_host]['tree']['date'] return json.dumps(data)
def tree_layout(id, path=''): response.content_type = 'application/json' # get node metadata tree = get_tree(cache[id]['tree'], path) children = tree['children'].keys() sizes = [tree['children'][child]['size'] for child in children] # filter out zero values children = filter(lambda child: tree['children'][child]['size'] > 0, children) sizes = filter(lambda size: size > 0, sizes) # sort the objects by size, descending order = argsort(sizes)[::-1] children = [children[i] for i in order] sizes = [sizes[i] for i in order] # compute the treemap layout sizes = squarify.normalize_sizes(sizes, width, height) rects = squarify.padded_squarify(sizes, 0, 0, width, height) # annotate rects with some metadata for (child, rect) in zip(children, rects): rect['host'] = cache[id]['meta']['host'] rect['path'] = os.path.join(path, child) rect['name'] = child rect['size'] = bytes2human(tree['children'][child]['size']) if len(tree['children'][child]['children']) == 0: rect['type'] = 'file' else: rect['type'] = 'dir' # if I am at a leaf node, then rects should be empty # in that case, add a single rectangle for the whole canvas if len(rects) == 0: rects.append({'x': 0, 'y': 0, 'dx': width, 'dy': height, 'host': cache[id]['meta']['host'], 'path': path, 'name': path.split('/')[-1], 'size': bytes2human(tree['size']), 'type': 'file'}) data = {} data['rects'] = rects data['size'] = tree['size'] data['humansize'] = bytes2human(tree['size']) data['date'] = cache[id]['tree']['date'] return json.dumps(data)
def calculatePositions(node, padding_threshold, level=0): if 'children' in node: x = node['x'] y = node['y'] dx = node['dx'] dy = node['dy'] if level == 0: node['children'].sort(key=lambda c: c['label']) padding = 5 if padding * (len(node['children']) - 1) > dx: padding = 0 dxMinusTotalPadding = dx - padding * (len(node['children']) - 1) childX = x for child in node['children']: child['y'] = y child['dy'] = dy child['x'] = childX child[ 'dx'] = child['size'] * dxMinusTotalPadding / node['size'] childX += child['dx'] + padding calculatePositions(child, padding_threshold, level + 1) else: if 'childrenSize' in node: childrenRatio = node['childrenSize'] / node['size'] if childrenRatio < 1: if dx > dy: dx = dx * childrenRatio else: dy = dy * childrenRatio node['children'].sort(reverse=True, key=lambda c: c['size']) sizes = squarify.normalize_sizes( list(map(lambda c: c['size'], node['children'])), dx, dy) if level < padding_threshold: rects = squarify.padded_squarify(sizes, x, y, dx, dy) else: rects = squarify.squarify(sizes, x, y, dx, dy) for child, rect in zip(node['children'], rects): for k, v in rect.items(): child[k] = v calculatePositions(child, padding_threshold, level + 1)
def main(): m = Map(80, 60) total_size = m.width * m.height rooms = [] while sum(rooms) < total_size: diff = total_size - sum(rooms) if diff > 6: roomsize = random.randint(6, min(total_size * 0.5, total_size - sum(rooms))) rooms.append(roomsize) else: rooms[-1] += diff print(rooms) data = squarify.padded_squarify(rooms, 0, 0, m.width, m.height) import json print(json.dumps(data, indent=2))
def _plot_groups_density(ax, groups_df, count_limit, width=5, height=10, padded=False): if groups_df.empty: return None # these values define the coordinate system for the returned rectangles # the values will range from x to x + width and y to y + height x = 0. y = 0. groups_df = groups_df.sort_values('size', ascending=False) values = groups_df['size'].values cumsum_val = np.cumsum(values) cutoff = min(max(np.argmax(cumsum_val >= count_limit), 1), MAX_RECT) values = values[:cutoff] colors = groups_df['length'].values colors = colors[:cutoff] # the sum of the values must equal the total area to be laid out # i.e., sum(values) == width * height values = squarify.normalize_sizes(values, width, height) if padded: rects = squarify.padded_squarify(values, x, y, width, height) else: rects = squarify.squarify(values, x, y, width, height) ax.set_xlim(0, width) ax.set_ylim(0, height) def to_patch(rect): return Rectangle((rect['x'], rect['y']), rect['dx'], rect['dy']) patches = map(to_patch, rects) collection = PatchCollection(patches, cmap=matplotlib.cm.plasma, alpha=0.9) collection.set_array(colors) ax.add_collection(collection) ax.set_yticklabels([]) ax.set_xticklabels([]) return collection
def get_treemapcoordinate(values): # these values define the coordinate system for the returned rectangles # the values will range from x to x + width and y to y + height x = 0. y = 0. width = 800. height = 600. # values must be sorted descending (and positive, obviously) # values.sort(reverse=True) # the sum of the values must equal the total area to be laid out # i.e., sum(values) == width * height values = squarify.normalize_sizes(values, width, height) # returns a list of rectangles rects = squarify.squarify(values, x, y, width, height) # padded rectangles will probably visualize better for certain cases padded_rects = squarify.padded_squarify(values, x, y, width, height) # result: # [ # { # "dy": 433, # "dx": 327.7153558052434, # "x": 0, # "y": 0 # }, # { # "dy": 330.0862676056338, # "dx": 372.2846441947566, # "x": 327.7153558052434, # "y": 0 # }, ... return padded_rects
def create_square_graph(value_dict, df_shape, plot_title): """ Plots a square area graph of demographic groups with label, value, and percent annotations Args: value_dict: dictionary with label of a demographic group with the number of participants in the group as the value df_shape: total number of participants in the dataset used to calculate the percent in each box plot_title: title of plot Returns: dict: containing plotly figure data and layout information """ values = [*value_dict.keys()] values.sort(reverse=True) #redefine label order labels = [value_dict[value] for value in values] percents = [(value / df_shape) * 100 for value in values] x = 0.0 y = 0.0 width = 100.0 height = 100.0 normed = squarify.normalize_sizes(values, width, height) rects = squarify.padded_squarify(normed, x, y, width, height) shapes = [] annotations = [ dict( yref="paper", xref="paper", y=1.10, x=0, text=f"<b>{plot_title}</b>", showarrow=False, font=dict(color="#323031"), ) ] for counter, r in enumerate(rects): if r['dy'] <= 10: text = f"<b>{labels[counter]}</b> {round(percents[counter],2)}%" if len(text) * 1.5 >= r['dx']: text = '' else: text = f"<b>{labels[counter]}</b><br>{round(percents[counter],2)}%" if len(labels[counter]) * 1.5 >= r['dx']: text = '' shapes.append( dict( type="rect", x0=r["x"], y0=r["y"], x1=r["x"] + r["dx"], y1=r["y"] + r["dy"], line=dict(width=2), fillcolor=color_palette[counter], )) annotations.append( dict( x=r["x"] + (r["dx"] / 2), y=r["y"] + (r["dy"] / 2), text=text, showarrow=False, font=dict(color="white"), )) fig_data = [ go.Scatter( x=[r["x"] + (r["dx"] / 2) for r in rects], y=[r["y"] + (r["dy"] / 2) for r in rects], text=[ f"{str(l)}<br>{str(v)} ppts.<br>{round(p, 2)}%" for l, v, p in zip(labels, values, percents) ], hoverinfo="x+text", ) ] fig_layout = dict( xaxis=dict( showgrid=False, zeroline=False, range=[0, 110], ticks="", showticklabels=False, ), yaxis=dict( showgrid=False, zeroline=False, range=[0, 110], ticks="", showticklabels=False, ), shapes=shapes, showlegend=False, annotations=annotations, margin={ "pad": 5, "l": 65, "r": 50, "t": 55, "b": 65 }, hovermode="closest", hoverdistance=-1, hoverlabel={ "bgcolor": "white", "font": { "color": "black" } }, title="", ) return dict(data=fig_data, layout=fig_layout)
(41, 127, 214), (27, 70, 163), (72, 17, 121), (209, 0, 89), (148, 0, 26), (223, 44, 13), (195, 215, 0)] # Scale the RGB values to the [0, 1] range, which is the format matplotlib accepts. for i in range(len(colors)): r, g, b = colors[i] colors[i] = (r / 255., g / 255., b / 255.) # values must be sorted descending (and positive, obviously) values.sort(reverse=True) # the sum of the values must equal the total area to be laid out # i.e., sum(values) == width * height values = squarify.normalize_sizes(values, width, height) # padded rectangles will probably visualize better for certain cases rects = squarify.padded_squarify(values, x, y, width, height) cmap = matplotlib.cm.get_cmap() color = [cmap(random.random()) for i in range(len(values))] x = [rect['x'] for rect in rects] y = [rect['y'] for rect in rects] dx = [rect['dx'] for rect in rects] dy = [rect['dy'] for rect in rects] ax.bar(x, dy, width=dx, bottom=y, color=colors, label=labels) va = 'center' idx = 1 for l, r, v in zip(labels, rects, initvalues):
def main(fname, ignore_files, n_largest): sections = parseSections(open(fname, 'r')) if sections is None: print( 'start of memory config not found, did you invoke the compiler/linker with LANG=C?' ) return sectionWhitelist = {'.text', '.data', '.bss', '.rodata'} plots = [] whitelistedSections = list( filter(lambda x: x.section in sectionWhitelist, sections)) allObjects = list(chain(*map(lambda x: x.children, whitelistedSections))) allFiles = list(set(map(lambda x: x.basepath, allObjects))) for s in whitelistedSections: objects = s.children groupsize = {} for k, g in groupby(sorted(objects, key=lambda x: x.basepath), lambda x: x.basepath): size = sum(map(lambda x: x.size, g)) groupsize[k] = size #objects.sort (reverse=True, key=lambda x: x.size) grouped_obj = [ GroupedObj(k, size) for k, size in groupsize.items() if k not in ignore_files ] grouped_obj.sort(reverse=True, key=lambda x: x.size) for i in range(0, n_largest): o = grouped_obj[i] print(f'{o.size:>8} {o.path}') values = list(map(lambda x: x.size, grouped_obj)) totalsize = sum(values) x = 0 y = 0 width = 1000 height = 1000 values = squarify.normalize_sizes(values, width, height) padded_rects = squarify.padded_squarify(values, x, y, width, height) # plot with bokeh output_file('linkermap.html', title='Linker map') left = list(map(lambda x: x['x'], padded_rects)) top = list(map(lambda x: x['y'], padded_rects)) rectx = list(map(lambda x: x['x'] + x['dx'] / 2, padded_rects)) recty = list(map(lambda x: x['y'] + x['dy'] / 2, padded_rects)) rectw = list(map(lambda x: x['dx'], padded_rects)) recth = list(map(lambda x: x['dy'], padded_rects)) files = list(map(lambda x: x.path, grouped_obj)) size = list(map(lambda x: x.size, grouped_obj)) #children = list (map (lambda x: ','.join (map (lambda x: x[1], x.children)) if x.children else x.section, grouped_obj)) legend = list( map(lambda x: '{} ({})'.format(x.path, x.size), grouped_obj)) source = ColumnDataSource(data=dict( left=left, top=top, x=rectx, y=recty, width=rectw, height=recth, file=files, size=size, # children=children, legend=legend, )) hover = HoverTool(tooltips=[ ("size", "@size"), ("file", "@file"), # ("symbol", "@children"), ]) p = figure(title='Linker map for section {} ({} bytes)'.format( s.section, totalsize), plot_width=width, plot_height=height, tools=[hover, 'pan', 'wheel_zoom', 'box_zoom', 'reset'], x_range=(0, width), y_range=(0, height)) p.xaxis.visible = False p.xgrid.visible = False p.yaxis.visible = False p.ygrid.visible = False palette = inferno(len(grouped_obj)) mapper = CategoricalColorMapper(palette=palette, factors=allFiles) p.rect(x='x', y='y', width='width', height='height', source=source, color={ 'field': 'file', 'transform': mapper }, legend='legend') # set up legend, must be done after plotting p.legend.location = "top_left" p.legend.orientation = "horizontal" plots.append(p) show(column(*plots, sizing_mode="scale_width"))