def get_svg_html(mpl_figures): svg_images = [] with make_tmp_folder() as tmp_dir: for fig in mpl_figures: tmp_svg = "%s/mplfig.svg" % (tmp_dir) fig.savefig(tmp_svg) fig_data = open(tmp_svg, "rb").readlines() svg_images.append(fig_data) return svg_images
def get_svg_html(mpl_figures): svg_images = [] with make_tmp_folder() as tmp_dir: for fig in mpl_figures: tmp_svg = "%s/mplfig.svg" %(tmp_dir) fig.savefig(tmp_svg) fig_data = open(tmp_svg,"rb").readlines() svg_images.append(fig_data) return svg_images
def get_static_svg(self): '''Generate static svg of atlas (cannot manipulate in d3)''' svg_data = [] with make_tmp_folder() as temp_dir: output_file='%s/atlas.svg' %(temp_dir) plotting.plot_roi(self.mr,annotate=False,draw_cross=False,cmap="nipy_spectral",black_bg=False, output_file=output_file) svg_file = open(output_file,'r') svg_data = svg_file.readlines() svg_file.close() return svg_data[4:]
def view(html_snippet): with make_tmp_folder() as tmp_dir: # Write to temporary file tmp_file = "%s/pycompare.html" % (tmp_dir) internal_view(html_snippet, tmp_file)
def make_svg(self,views): '''Generate path-based svg of atlas (paths we can manipulate in d3)''' import cairo # We will save complete svg (for file), partial (for embedding), and paths svg_data = dict(); svg_data_partial = dict(); svg_data_file = dict(); if isinstance(views,str): views = [views] views = [v.lower() for v in views] self.views = views mr = self.mr.get_data() middles = [numpy.round(x/2) for x in self.mr.get_shape()] # Create a color lookup table colors_html = get_colors(len(self.labels),"hex") self.color_lookup = self.make_color_lookup(colors_html) with make_tmp_folder() as temp_dir: # Get all unique regions (may not be present in every slice) regions = [ x for x in numpy.unique(mr) if x != 0] # Get colors - will later be changed colors = get_colors(len(self.labels),"decimal") # Generate an axial, sagittal, coronal view slices = dict() for v in views: # Keep a list of region names that correspond to paths region_names = [] # Generate each of the views if v == "axial": slices[v] = numpy.rot90(mr[:,:,middles[0]],2) elif v == "sagittal" : slices[v] = numpy.rot90(mr[middles[1],:,:],2) elif v == "coronal" : slices[v] = numpy.rot90(mr[:,middles[2],:],2) # For each region in the view, but not 0 regions = [ x for x in numpy.unique(slices[v]) if x != 0] # Write svg to temporary file output_file = '%s/%s_atlas.svg' %(temp_dir,v) fo = file(output_file, 'wb') # Set up the "context" - what cairo calls a canvas width, height = numpy.shape(slices[v]) surface = cairo.SVGSurface (fo, width*3, height*3) ctx = cairo.Context (surface) ctx.scale(3.,3.) # 90 degree rotation matrix rotation_matrix = cairo.Matrix.init_rotate(numpy.pi/2) for rr in range(0,len(regions)): index_value = regions[rr] #region_name = self.labels[str(index_value)].label filtered = numpy.zeros(numpy.shape(slices[v])) filtered[slices[v] == regions[rr]] = 1 region = img_as_float(find_boundaries(filtered)) # We aren't using Canny anymore... ctx.set_source_rgb (float(colors[index_value-1][0]), float(colors[index_value-1][1]), float(colors[index_value-1][2])) # Solid color # Segment! segments_fz = felzenszwalb(region, scale=100, sigma=0.1, min_size=10) # For each cluster in the region, skipping value of 0 for c in range(1,len(numpy.unique(segments_fz))): cluster = numpy.zeros(numpy.shape(region)) cluster[segments_fz==c] = 1 # Create distance matrix for points x,y = numpy.where(cluster==1) points = [[x[i],y[i]] for i in range(0,len(x))] disty = squareform(pdist(points, 'euclidean')) # This keeps track of which we have already visited visited = []; row = 0; current = points[row] visited.append(row) # We need to remember the first point, for the last one fp = current while len(visited) != len(points): thisx = current[0] thisy = current[1] ctx.move_to(thisx, thisy) # Find closest point, only include columns we have not visited distances = disty[row,:] distance_lookup = dict() # We need to preserve indices but still eliminate visited for j in range(0,len(distances)): if j not in visited: distance_lookup[j] = distances[j] # Get key minimum distance row = min(distance_lookup, key=distance_lookup.get) next = points[row] nextx = next[0] nexty = next[1] # If the distance is more than N pixels, close the path # This resolves some of the rough edges too if min(distance_lookup) > 70: ctx.line_to(fp[0],fp[1]) #cp = [(current[0]+fp[0])/2,(current[1]+fp[1])/2] #ctx.curve_to(fp[0],fp[1],cp[0],cp[1],cp[0],cp[1]) ctx.set_line_width(1) ctx.close_path() fp = next else: #cp = [(current[0]+nextx)/2,(current[1]+nexty)/2] #ctx.curve_to(nextx,nexty,cp[0],cp[1],cp[0],cp[1]) ctx.line_to(nextx, nexty) # Set next point to be current visited.append(row) current = next # Go back to the first point ctx.move_to(current[0],current[1]) #cp = [(current[0]+fp[0])/2,(current[1]+fp[1])/2] #ctx.curve_to(fp[0],fp[1],cp[0],cp[1],cp[0],cp[1]) ctx.line_to(fp[0],fp[1]) # Close the path ctx.set_line_width (1) ctx.stroke() # Finish the surface surface.finish() fo.close() # Now grab the file, set attributes # Give group name based on atlas, region id based on matching color dom = minidom.parse(output_file) for group in dom.getElementsByTagName("g"): group.setAttribute("id",os.path.split(self.file)[-1]) group.setAttribute("class",v) expression = re.compile("stroke:rgb") # Add class to svg - important so can manipulate in d3 dom.getElementsByTagName("svg")[0].setAttribute("class",v) for path in dom.getElementsByTagName("path"): style = path.getAttribute("style") # This is lame - but we have to use the color to look up the region color = [x for x in style.split(";") if expression.search(x)][0] color = [percent_to_float(x) for x in color.replace("stroke:rgb(","").replace(")","").split(",")] region_index = [x for x in range(0,len(colors)) if numpy.equal(colors[x],color).all()][0]+1 region_label = self.labels[str(region_index)].label # We don't want to rely on cairo to style the paths self.remove_attributes(path,"style") self.set_attributes(path,["id","stroke"],[region_label,self.color_lookup[region_label]]) svg_data_file[v] = dom.toxml() svg_data[v] = dom.toxml().replace("<?xml version=\"1.0\" ?>","") # get rid of just xml tag svg_data_partial[v] = "/n".join(dom.toxml().split("\n")[1:-1]) return svg_data, svg_data_partial, svg_data_file
def view(html_snippet): with make_tmp_folder() as tmp_dir: # Write to temporary file tmp_file = "%s/pycompare.html" %(tmp_dir) internal_view(html_snippet,tmp_file)
def make_svg(self, views): '''Generate path-based svg of atlas (paths we can manipulate in d3)''' import cairo # We will save complete svg for file, partial for embedding, and paths svg_data = dict() svg_data_partial = dict() svg_data_file = dict() if isinstance(views, str): views = [views] self.views = [v.lower() for v in views] mr = self.mr.get_data() middles = [numpy.round(old_div(x, 2)) for x in self.mr.get_shape()] # Create a color lookup table colors_html = get_colors(len(self.labels), "hex") self.color_lookup = self.make_color_lookup(colors_html) with make_tmp_folder() as temp_dir: # Get all unique regions (may not be present in every slice) regions = [x for x in numpy.unique(mr) if x != 0] # Get colors - will later be changed colors = get_colors(len(self.labels), "decimal") # Generate an axial, sagittal, coronal view slices = dict() for v in views: # Keep a list of region names that correspond to paths region_names = [] # Generate each of the views if v == "axial": slices[v] = numpy.rot90(mr[:, :, middles[0]], 2) elif v == "sagittal": slices[v] = numpy.rot90(mr[middles[1], :, :], 2) elif v == "coronal": slices[v] = numpy.rot90(mr[:, middles[2], :], 2) # For each region in the view, but not 0 regions = [x for x in numpy.unique(slices[v]) if x != 0] # Write svg to temporary file output_file = '%s/%s_atlas.svg' % (temp_dir, v) fo = file(output_file, 'wb') # Set up the "context" - what cairo calls a canvas width, height = numpy.shape(slices[v]) surface = cairo.SVGSurface(fo, width * 3, height * 3) ctx = cairo.Context(surface) ctx.scale(3., 3.) # 90 degree rotation matrix rotation_matrix = cairo.Matrix.init_rotate(old_div( numpy.pi, 2)) for rr in range(0, len(regions)): index_value = regions[rr] #region_name = self.labels[str(index_value)].label filtered = numpy.zeros(numpy.shape(slices[v])) filtered[slices[v] == regions[rr]] = 1 # We aren't using Canny anymore... region = img_as_float(find_boundaries(filtered)) # Solid color ctx.set_source_rgb(float(colors[index_value - 1][0]), float(colors[index_value - 1][1]), float(colors[index_value - 1][2])) # Segment! segments_fz = felzenszwalb(region, scale=100, sigma=0.1, min_size=10) # For each cluster in the region, skipping value of 0 for c in range(1, len(numpy.unique(segments_fz))): cluster = numpy.zeros(numpy.shape(region)) cluster[segments_fz == c] = 1 # Create distance matrix for points x, y = numpy.where(cluster == 1) points = [[x[i], y[i]] for i in range(0, len(x))] disty = squareform(pdist(points, 'euclidean')) # This keeps track of which we have already visited visited = [] row = 0 current = points[row] visited.append(row) # We need to remember the first point, for the last one fp = current while len(visited) != len(points): thisx = current[0] thisy = current[1] ctx.move_to(thisx, thisy) # Find closest point, only include cols not visited distances = disty[row, :] distance_lookup = dict() # preserve indices but still eliminate visited for j in range(0, len(distances)): if j not in visited: distance_lookup[j] = distances[j] # Get key minimum distance row = min(distance_lookup, key=distance_lookup.get) next = points[row] nextx = next[0] nexty = next[1] # If the distance is more than N pixels, close path # This resolves some of the rough edges too if min(distance_lookup) > 70: ctx.line_to(fp[0], fp[1]) ctx.set_line_width(1) ctx.close_path() fp = next else: ctx.line_to(nextx, nexty) # Set next point to be current visited.append(row) current = next # Go back to the first point ctx.move_to(current[0], current[1]) ctx.line_to(fp[0], fp[1]) # Close the path ctx.set_line_width(1) ctx.stroke() # Finish the surface surface.finish() fo.close() # Now grab the file, set attributes # group name based on atlas, region id based on matching color dom = minidom.parse(output_file) for group in dom.getElementsByTagName("g"): group.setAttribute("id", os.path.split(self.file)[-1]) group.setAttribute("class", v) regexp = re.compile("stroke:rgb") # Add class to svg - important so can manipulate in d3 dom.getElementsByTagName("svg")[0].setAttribute("class", v) for path in dom.getElementsByTagName("path"): style = path.getAttribute("style") # we have to use the color to look up the region color = [x for x in style.split(";") if regexp.search(x)][0] color = [ percent_to_float(x) for x in color.replace( "stroke:rgb(", "").replace(")", "").split(",") ] region_index = [ x for x in range(0, len(colors)) if numpy.equal(colors[x], color).all() ][0] + 1 region_label = self.labels[str(region_index)].label # We don't want to rely on cairo to style the paths self.remove_attributes(path, "style") self.set_attributes( path, ["id", "stroke"], [region_label, self.color_lookup[region_label]]) svg_data_file[v] = dom.toxml() # get rid of just xml tag svg_data[v] = dom.toxml().replace("<?xml version=\"1.0\" ?>", "") svg_data_partial[v] = "/n".join(dom.toxml().split("\n")[1:-1]) return svg_data, svg_data_partial, svg_data_file