def compute_local_coordinates(groups, name): """ Compute local coordinates of a structure relatively to major and minor axes. """ points = groups[name]["coords"]["global"] # Distance to major axis (X) path = svg.path(svg_filename, "%s-major-axis" % name) verts, codes = svg.tesselate(path.vertices, path.codes) X = geometry.signed_distance_polyline(verts, points) # Distance to minor axis (Y) path = svg.path(svg_filename, "%s-minor-axis" % name) verts, codes = svg.tesselate(path.vertices, path.codes) Y = geometry.signed_distance_polyline(verts, points) # Differetial normalization X /= np.abs(X).max() Y /= np.abs(Y).max() # Common normalization #m = max(np.abs(X).max(), np.abs(Y).max()) #X /= m #Y /= m groups[name]["coords"]["local"] = np.dstack([X, Y]).squeeze() return groups[name]["coords"]["local"]
def _make_key_paths( width = 50, height = 50, radius = 4 ): w = float( width ) # bounding-box horizontal dimension wh = w / 2.0 # half of that dimension h = float( height ) # bounding-box vertical dimension hh = h / 2.0 # half of that dimension r = float( radius ) # corner radius b = r / 2.0 # apparent border bh = b / 2.0 # half of that dimension xd = w - ( 2.0 * r ) # horizontal dimension between radii xdh = xd / 2.0 # half of that dimension yd = h - ( 2.0 * r ) # vertical dimension between radii ydh = yd / 2.0 # half of that dimension return [ svg.path( { 'd' : [ [ 'M', r, 0 ], [ 'l', xd, 0 ], [ 'q', r, 0, r, r ], [ 'l', 0, yd ], [ 'q', 0, r, -r, r ], [ 'l', -xd, 0 ], [ 'q', -r, 0, -r, -r ], [ 'l', 0, -yd ], [ 'q', 0, -r, r, -r ], [ 'z' ] ], 'class' : 'key_back' } ), svg.path( { 'd' : [ [ 'M', r, b ], [ 'l', xd, 0 ], [ 'q', b, 0, b, b ], [ 'l', 0, ydh ], [ 'l', -( w - r ), 0 ], [ 'l', 0, -ydh ], [ 'q', 0, -b, b, -b ], [ 'z' ] ], 'class' : 'key_top' } ), svg.path( { 'd' : [ [ 'M', b, hh ], [ 'l', ( w - r ), 0 ], [ 'l', 0, ydh ], [ 'q', 0, b, -b, b ], [ 'l', -xd, 0 ], [ 'q', -b, 0, -b, -b ], [ 'l', 0, -ydh ], [ 'z' ] ], 'class' : 'key_bottom' } ) ]
def write_polygon_projection_svg(f, facepaths, sheetwidth, padding, use_numbers, use_map, center_dot, comment): x, y = padding, padding w, cur_h = 0., 0. pos = [] for i, face in enumerate(facepaths): min_x, min_y, max_x, max_y = face['bbox'] face_w, face_h = max_x-min_x, max_y-min_y if x + face_w > sheetwidth: y += cur_h + padding x, cur_h = padding, 0. pos.append( (x-min_x, y-min_y) ) cur_h = max(cur_h, face_h) x += face_w + padding w = max(w, x) h = y + cur_h + padding w, h = int(math.ceil(w)), int(math.ceil(h)) f.write(svg.header(w,h)) f.write('<title><![CDATA['+comment+']]></title>') for i, face in enumerate(facepaths): x, y = pos[i] borders_path = svg.polygon_path(face['borders']) # borders_path = svg.polygon_path(face['borders']) + ''.join(svg.polygon_path(s) for s in face['slots']) projection_path = svg.polygon_multipath(face['projection']) borders = svg.path( borders_path, style=cut ) if use_map: engraving = svg.group( svg.path( borders_path, style=engrave )+ svg.path( projection_path, style=engrave ), id='engrave_'+str(i) ) else: engraving = '' if use_numbers: text = svg.text(0,2.5, str(i), style=commentstyle+';'+textstyle ) for n, a, b in zip(face['neighbours'], face['points'], face['points'][1:]+face['points'][:1]): x1, y1 = a x2, y2 = b dx, dy = (x1+x2)/3., (y1+y2)/3.+1.5 text += svg.text(dx,dy, str(n), style=commentstyle+';'+smalltextstyle ) else: text = '' if center_dot: dot = svg.circle(.1, style=cut) else: dot = '' f.write(svg.group( svg.group(borders + engraving) + text + dot, transform='translate('+str(x)+' '+str(y)+')', id='face_'+str(i) )) f.write(svg.footer())
def get_char(c, relx, style, glyph_cache=[]): g = get_glyph(c) if c in glyph_cache: p = svg.use(get_char_id(c), "translate(%g 0)" % relx) else: glyph_cache.append(c) regions = filter(None, g['path'].split('Z')) styles = map(lambda x: style[x], g['colouring']) paths = "".join(svg.path(r+'Z', s) for (r, s) in zip(regions, styles)) p = svg.group(svg.group(paths, "scale(1 -1)", id=get_char_id(c)), "translate(%g 0)" % relx) return (g['advance'], p)
jagged_longedge(c, d, angle, thickness, overhang, overcut), jagged_shortedge(d, a, angle, thickness, overhang, overcut), ) return [ c for e in edges for c in e ] def slots(radius): edges = [] a, b, c, d = ( (x*radius, y*radius) for x,y in dhxdron_deltoid_2d_coords() ) return ( slot_short(a, b, native_scale), slot_long(b, c, native_scale), slot_long(c, d, native_scale), slot_short(d, a, native_scale), ) style = 'stroke:none;fill:#0000ff;opacity:.3' print svg.header(radius*2,radius*2) print '<g transform="translate('+str(radius)+' '+str(radius)+')">' print svg.circle(radius, style) print svg.path( svg.polygon_path(shape(radius=radius, thickness=thickness)), style) for slot in slots(radius=radius): print svg.path( svg.polygon_path(slot), style) print '</g>' print svg.footer()
if ids[I[i]] != ids[I[i - 1]] or i == len(ids) - 1: if i == len(ids) - 1: end = i + 1 else: end = i for name, group in groups.items(): if group["id"] == ids[I[start]]: group["indices"] = start, end group["coords"]["global"] = global_coords[start:end] group["facecolors"] = facecolors[start:end] group["edgecolors"] = edgecolors[start:end] start = i global_coords[...] = global_coords[I] # Get individual paths groups["Caudate"]["border"] = svg.path(svg_filename, "Caudate") groups["Caudate"]["major-axis"] = svg.path(svg_filename, "Caudate-major-axis") groups["Caudate"]["minor-axis"] = svg.path(svg_filename, "Caudate-minor-axis") groups["Caudate"]["input"] = svg.path(svg_filename, "Caudate-input") groups["GPe"]["border"] = svg.path(svg_filename, "GPe") groups["GPe"]["major-axis"] = svg.path(svg_filename, "GPe-major-axis") groups["GPe"]["minor-axis"] = svg.path(svg_filename, "GPe-minor-axis") groups["GPi"]["border"] = svg.path(svg_filename, "GPi") groups["GPi"]["major-axis"] = svg.path(svg_filename, "GPi-major-axis") groups["GPi"]["minor-axis"] = svg.path(svg_filename, "GPi-minor-axis") groups["GPi"]["output"] = svg.path(svg_filename, "GPi-output") # ------------------------------------------------------------- Computation --- def compute_local_coordinates(groups, name): """
polygon.draw(gl.GL_TRIANGLES, I) gl.glLineWidth(1.0) polygon["color"] = 0.50, 0.50, 0.50, 1.00 gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE) polygon.draw(gl.GL_TRIANGLES, I) gl.glLineWidth(3.0) polygon["color"] = 0.00, 0.00, 0.00, 1.00 polygon.draw(gl.GL_LINE_LOOP, O) def triangulate(vertices): n = len(vertices) segments = (np.repeat(np.arange(n + 1), 2)[1:-1]) % n T = triangle.triangulate({'vertices': vertices, 'segments': segments}, "p") return T["vertices"], T["triangles"] V, C = svg.path("firefox.svg", "firefox") V = .95 * (2 * (V - V.min()) / (V.max() - V.min()) - 1) V[:, 1] = -V[:, 1] V, I = triangulate(V) polygon = gloo.Program(vertex, fragment, count=len(V)) polygon["position"] = V I = I.astype(np.uint32).view(gloo.IndexBuffer) O = (np.repeat(np.arange(len(V) + 1), 2)[1:-1]) % len(V) O = O.astype(np.uint32).view(gloo.IndexBuffer) app.run()
def plot(series, bins=40, smoothing=1, range_x=(0, 1), range_y=(0, 1), major=(0.1, 0.1), minor=(2, 2), title=None, subtitle=None, label_x=None, label_y=None, legend={}, colors={}): resolution = 20 * bins kernel_width = smoothing / bins display = 800, 400 margin_x = 120, 120 margin_y = 80, 50 + 10 * (subtitle is not None) + 20 * (title is not None) area = display[0] - sum(margin_x), sum(margin_y) - display[1] offset = margin_x[0], display[1] - margin_y[0] start, end = range_x low, high = range_y # epsilon deals with floating point error cells = int((end - start) / major[0] * minor[0] + 1e-5), int((high - low) / major[1] * minor[1] + 1e-5) grid_minor = [] grid_major = [] ticks = [] labels = [] for i in range(cells[0] + 1): x = i * major[0] / (minor[0] * (end - start)) v = i * major[0] / minor[0] + start m = i % minor[0] == 0 screen = tuple( tuple(map(round, transform(x, area, offset))) for x in ((x, 0), (x, 1))) length = 12 if m else 6 (grid_major if m else grid_minor).append( svg.path( (transform(screen[0], (1, 1), (0.5, 0)), transform(screen[1], (1, 1), (0.5, -1))), classes=('grid', 'grid-major' if m else 'grid-minor'))) ticks.append( svg.path((transform(screen[0], (1, 1), (0.5, 8)), transform(screen[0], (1, 1), (0.5, 8 + length))), classes=('tick', ))) if m: labels.append( svg.text(str(round(v, 3)), position=transform(screen[0], (1, 1), (0, 16 + length)), classes=('label-numeric', 'label-x'))) for i in range(cells[1] + 1): y = i * major[1] / (minor[1] * (high - low)) v = i * major[1] / minor[1] + low m = i % minor[1] == 0 screen = tuple( tuple(map(round, transform(y, area, offset))) for y in ((0, y), (1, y))) length = 12 if m else 6 (grid_major if m else grid_minor).append( svg.path( (transform(screen[0], (1, 1), (0, -0.5)), transform(screen[1], (1, 1), (1, -0.5))), classes=('grid', 'grid-major' if m else 'grid-minor'))) ticks.append( svg.path((transform(screen[0], (1, 1), (-8, -0.5)), transform(screen[0], (1, 1), (-8 - length, -0.5))), classes=('tick', ))) if m: labels.append( svg.text(str(round(v, 3)), position=transform(screen[0], (1, 1), (-16 - length, 0)), classes=('label-numeric', 'label-y'))) paths = [] # emit using the same ordering as `colors` for name, *_ in colors: scale = 1 / (bins * len(series[name])) curve = tuple((x / resolution, (sum( kernel(x / resolution, (point - start) / (end - start), kernel_width) for point in series[name]) * scale - low) / (high - low)) for x in range(resolution + 1)) paths.append( svg.path(map(lambda x: transform(x, area, offset), curve), classes=(name, 'density-curve'))) for i, (name, label) in enumerate(legend): base = tuple(map(round, transform((1, 1), area, offset))) dy = 20 * i paths.append( svg.path((transform(base, (1, 1), (10, dy)), transform(base, (1, 1), (25, dy))), classes=(name, 'density-curve'))) labels.append( svg.text(label, position=transform(base, (1, 1), (32, dy)), classes=('label-legend', ))) if type(title) is str: screen = tuple(map(round, transform((0.5, 1), area, offset))) labels.append( svg.text(title, position=transform(screen, (1, 1), (0, -40)), classes=('title', ))) if type(subtitle) is str: screen = tuple(map(round, transform((0.5, 1), area, offset))) labels.append( svg.text(subtitle, position=transform(screen, (1, 1), (0, -20)), classes=('subtitle', ))) if type(label_x) is str: screen = tuple(map(round, transform((0.5, 0), area, offset))) labels.append( svg.text(label_x, position=transform(screen, (1, 1), (0, 50)), classes=('label-axis', 'label-x'))) if type(label_y) is str: screen = tuple(map(round, transform((0, 0.5), area, offset))) labels.append( svg.text(label_y, position=transform(screen, (1, 1), (-80, 0)), classes=('label-axis', 'label-y', 'label-vertical'))) def linestyle(color, line): properties = [('stroke', color)] if line == 'dashed': properties.append(('stroke-dasharray', '6 3')) return '\n'.join(' {0}: {1};'.format(property, value) for property, value in properties) style = ''' rect.background { fill: white; } path.grid { stroke-width: 1px; fill: none; } path.grid-major { stroke: #eeeeeeff; } path.grid-minor { stroke: #f5f5f5ff; } path.tick { stroke-width: 1px; stroke: #333333ff; fill: none; } text { fill: #333333ff; font-family: 'SF Mono'; } text.label-numeric { font-size: 12px; } text.label-x { text-anchor: middle; dominant-baseline: hanging; } text.label-y { text-anchor: end; dominant-baseline: middle; } text.label-legend { font-size: 12px; text-anchor: begin; dominant-baseline: middle; } text.label-axis { font-size: 14px; font-weight: 700; } text.label-vertical.label-y { text-anchor: middle; transform-box: fill-box; transform-origin: center; transform: rotate(-90deg); } text.title, text.subtitle { text-anchor: middle; } text.title { font-size: 20px; } text.subtitle { font-size: 12px; } path.density-curve { stroke-linejoin: round; stroke-width: 2px; fill: none; } ''' + ''.join(''' path.{0} {{ {1} }} '''.format(name, linestyle(color, line)) for name, color, line in colors) return svg.svg(display, style, grid_minor + grid_major + ticks + paths + labels)
# Collect data data = np.genfromtxt(dat_filename, names=True, delimiter=';') density = data["Neu_Dens_SA"] density /= density.max() # Generate path names n_paths = len(density) pathnames = [] for i in range(0, n_paths): pathnames.append("%s" % (1 + i)) # Iterating over all paths to get extents xmin, xmax = 1e10, -1e10 ymin, ymax = 1e10, -1e10 for i, pathname in enumerate(pathnames): path = svg.path(svg_filename, pathname) verts = path.vertices xmin = min(xmin, verts[:, 0].min()) xmax = max(xmax, verts[:, 0].max()) ymin = min(ymin, verts[:, 1].min()) ymax = max(ymax, verts[:, 1].max()) scale = (size - 2 * border) / max(abs(xmax - xmin), abs(ymax - ymin)) x_extent = abs(xmax - xmin) * scale y_extent = abs(ymax - ymin) * scale x_offset = (size - x_extent) // 2 y_offset = (size - y_extent) // 2 # Resize patches for i, pathname in enumerate(pathnames): path = svg.path(svg_filename, pathname) verts, codes = path.vertices, path.codes
def makecircle(magnitude, salience, benefit=1): if c.swapsaliencemagnitude: tm = salience[:] salience = magnitude[:] magnitude = tm #general variables indicatorseparatorangles = [-math.pi*2/21*i + math.pi/21 for i in range(0,22)] indicatorcenterangles = [-math.pi*2/21*i for i in range(0,21)] wedgeangle = math.pi*2/21 out = svg.svg(width=1000, height=1000+100*c.saliencelegend, viewbox='0 0 1000 1%d00' % (1*c.saliencelegend==True)) if(benefit): colors=c.colorsbenefit else: colors=c.colorscost if c.centerlabel is not None: out.add(svg.text(c.centerlabel[1-benefit], 500, 500, fontsize=c.font, p='style="text-anchor: middle; dominant-baseline: middle"')) #draw wedges for i in range(0,21): r = ringradii(magnitude[i]+c.includezeromagnitude) if(c.saliencebywidth==1): wedgewidth = wedgeangle/2/(3+c.includezerosalience)*(salience[i]+c.includezerosalience) elif(c.saliencebywidth>1): wedgewidth = wedgeangle/2/(saliencebywidth**3)*(c.saliencebywidth**salience[i]) else: wedgewidth = wedgeangle/2 x1 = (500 + math.cos(indicatorcenterangles[i]+wedgewidth)*c.centerradius) y1 = (500 + math.sin(indicatorcenterangles[i]+wedgewidth)*c.centerradius) x2 = (500 + math.cos(indicatorcenterangles[i]+wedgewidth)*r) y2 = (500 + math.sin(indicatorcenterangles[i]+wedgewidth)*r) x3 = (500 + math.cos(indicatorcenterangles[i]-wedgewidth)*r) y3 = (500 + math.sin(indicatorcenterangles[i]-wedgewidth)*r) x4 = (500 + math.cos(indicatorcenterangles[i]-wedgewidth)*c.centerradius) y4 = (500 + math.sin(indicatorcenterangles[i]-wedgewidth)*c.centerradius) if(c.saliencebycolor): s = ((salience[i]+c.includezerosalience)**c.saliencebycolor)/((3.0+c.includezerosalience)**c.saliencebycolor) else: s = 1 red,green,blue = colors[i//7] d = 'M %s,%s L %s,%s A %s,%s 0 0,0 %s,%s L %s,%s A %s,%s 0 0,1 %s,%s' % (x1,y1,x2,y2,r,r,x3,y3,x4,y4,c.centerradius,c.centerradius,x1,y1) if(salience[i]>0 or c.includezerosalience): out.add(svg.path(d, fill='rgb(%s,%s,%s)' % (red,green,blue), p='fill-opacity="%s"' % s)) #draw dividers and text for i in range(0,21): if(c.saliencebywidth and c.drawsaliencedividers): x1 = (500 + math.cos(indicatorcenterangles[i])*c.centerradius) y1 = (500 + math.sin(indicatorcenterangles[i])*c.centerradius) x2 = (500 + math.cos(indicatorcenterangles[i])*c.edgeradius) y2 = (500 + math.sin(indicatorcenterangles[i])*c.edgeradius) out.add(svg.line(x1, y1, x2, y2, 'black', .5)) for j in range(1-c.includezerosalience,3): if(c.saliencebywidth>1): wedgewidth = wedgeangle/2/(c.saliencebywidth**3)*(c.saliencebywidth**j) else: wedgewidth = wedgeangle/2/(3+c.includezerosalience)*(j+c.includezerosalience) for k in [1,-1]: x1 = (500 + math.cos(indicatorcenterangles[i]+wedgewidth*k)*c.centerradius) y1 = (500 + math.sin(indicatorcenterangles[i]+wedgewidth*k)*c.centerradius) x2 = (500 + math.cos(indicatorcenterangles[i]+wedgewidth*k)*c.edgeradius) y2 = (500 + math.sin(indicatorcenterangles[i]+wedgewidth*k)*c.edgeradius) out.add(svg.line(x1, y1, x2, y2, 'black', .5)) #invisible link and tooltip box x1 = (500 + math.cos(indicatorcenterangles[i]+wedgeangle/2)*c.centerradius) y1 = (500 + math.sin(indicatorcenterangles[i]+wedgeangle/2)*c.centerradius) x2 = (500 + math.cos(indicatorcenterangles[i]+wedgeangle/2)*c.textradius+25) y2 = (500 + math.sin(indicatorcenterangles[i]+wedgeangle/2)*c.textradius+25) x3 = (500 + math.cos(indicatorcenterangles[i]-wedgeangle/2)*c.textradius+25) y3 = (500 + math.sin(indicatorcenterangles[i]-wedgeangle/2)*c.textradius+25) x4 = (500 + math.cos(indicatorcenterangles[i]-wedgeangle/2)*c.centerradius) y4 = (500 + math.sin(indicatorcenterangles[i]-wedgeangle/2)*c.centerradius) d = 'M %s,%s L %s,%s L %s,%s L %s,%s z' % (x1,y1,x2,y2,x3,y3,x4,y4) newpath = svg.path(d, fill='white', p='fill-opacity="0.0"') newpath.add(svg.title(' %s: %s\n Magnitude %s\tSalience %s' % (c.indicatornames[i], c.indicatorfullnames[i], magnitude[i], salience[i]))) out.add(newpath) x = (500 + math.cos(indicatorcenterangles[i])*c.textradius) y = (500 + math.sin(indicatorcenterangles[i])*c.textradius) out.add(svg.text(c.indicatornames[i], x, y, fontsize=c.font, p='style="text-anchor: middle; dominant-baseline: middle"')) # draw dividers x1 = 500 + math.cos(indicatorseparatorangles[i])*c.centerradius y1 = 500 + math.sin(indicatorseparatorangles[i])*c.centerradius if(i % 7 == 0): x2 = 500 + math.cos(indicatorseparatorangles[i])*(c.textradius+25) y2 = 500 + math.sin(indicatorseparatorangles[i])*(c.textradius+25) out.add(svg.line(x1, y1, x2, y2, 'black', 10)) elif (c.xgrid or (c.saliencebywidth and c.drawsaliencedividers)): x2 = 500 + math.cos(indicatorseparatorangles[i])*(c.textradius) y2 = 500 + math.sin(indicatorseparatorangles[i])*(c.textradius) out.add(svg.line(x1, y1, x2, y2, 'black', 2)) #draw rings for i in range(0,c.maxvalue+c.includezeromagnitude+1): if(i==c.includezeromagnitude): w=5 out.add(svg.circle('500','500',ringradii(i),'black',w,'none')) elif (c.ygrid or i==0): w=1 out.add(svg.circle('500','500',ringradii(i),'black',w,'none')) return out
def makemagnitudelegend(): angles = [-math.pi/2,math.pi/2] wedgeangle = math.pi*2/21 out = svg.svg(width=250, height=1000, viewbox='0 0 250 1000') x = (500 + math.cos(angles[0])*c.textradius) y = (500 + math.sin(angles[0])*c.textradius) if c.swapsaliencemagnitude: te = 'Salience:' else: te = 'Magnitude:' out.add(svg.text(te, 125, 25, fontsize=c.font, p='style="text-anchor: middle; dominant-baseline: middle"')) for angle in angles: x1 = (125 + math.cos(angle+wedgeangle/2)*c.centerradius) y1 = (500 + math.sin(angle+wedgeangle/2)*c.centerradius) x2 = (125 + math.cos(angle+wedgeangle/2)*c.textradius) y2 = (500 + math.sin(angle+wedgeangle/2)*c.textradius) x3 = (125 + math.cos(angle-wedgeangle/2)*c.textradius) y3 = (500 + math.sin(angle-wedgeangle/2)*c.textradius) x4 = (125 + math.cos(angle-wedgeangle/2)*c.centerradius) y4 = (500 + math.sin(angle-wedgeangle/2)*c.centerradius) out.add(svg.line(x1, y1, x2, y2, 'black', 2)) out.add(svg.line(x3, y3, x4, y4, 'black', 2)) if(c.drawsaliencedividers): x1 = (125 + math.cos(angle)*c.centerradius) y1 = (500 + math.sin(angle)*c.centerradius) x2 = (125 + math.cos(angle)*c.edgeradius) y2 = (500 + math.sin(angle)*c.edgeradius) out.add(svg.line(x1, y1, x2, y2, 'black', .5)) for j in range(1-c.includezerosalience,3): if(c.saliencebywidth>1): wedgewidth = wedgeangle/2/(c.saliencebywidth**3)*(c.saliencebywidth**j) else: wedgewidth = wedgeangle/2/(3+c.includezerosalience)*(j+c.includezerosalience) x1 = (125 + math.cos(angle-wedgewidth)*c.centerradius) y1 = (500 + math.sin(angle-wedgewidth)*c.centerradius) x2 = (125 + math.cos(angle-wedgewidth)*c.edgeradius) y2 = (500 + math.sin(angle-wedgewidth)*c.edgeradius) out.add(svg.line(x1, y1, x2, y2, 'black', .5)) x1 = (125 + math.cos(angle+wedgewidth)*c.centerradius) y1 = (500 + math.sin(angle+wedgewidth)*c.centerradius) x2 = (125 + math.cos(angle+wedgewidth)*c.edgeradius) y2 = (500 + math.sin(angle+wedgewidth)*c.edgeradius) out.add(svg.line(x1, y1, x2, y2, 'black', .5)) for i in range(0,c.maxvalue+c.includezeromagnitude+1): if(i==c.includezeromagnitude): w=5 else: w=1 r=ringradii(i) x1 = (125 + math.cos(angle+wedgeangle/1.5)*r) y1 = (500 + math.sin(angle+wedgeangle/1.5)*r) x2 = (125 + math.cos(angle-wedgeangle/1.5)*r) y2 = (500 + math.sin(angle-wedgeangle/1.5)*r) d = 'M %s,%s A %s,%s 0 0,0 %s,%s' % (x1,y1,r,r,x2,y2) out.add(svg.path(d, stroke='black', strokewidth=w)) y = y1 if(i%2==0): x = x2 + 10*angle else: x = x1 - 10*angle if(i-c.includezeromagnitude>=0): out.add(svg.text(i-c.includezeromagnitude, x, y, fontsize=c.font, p='style="text-anchor: middle; dominant-baseline: middle"')) return out
def plot(ratios, range_x = (0, 2), major = 1.0, minor = 5, title = None, subtitle = None, colors = {}): display = 800, 680 margin_x = 60, 60 margin_y = 20, 80 + 10 * (subtitle is not None) + 20 * (title is not None) area = display[0] - sum(margin_x), sum(margin_y) - display[1] offset = margin_x[0], display[1] - margin_y[0] # draw grid lines start, end = range_x # epsilon to deal with rounding errors cells = int((end - start) / major * minor + 1e-5) grid_minor = [] grid_major = [] ticks = [] labels = [] for i in range(cells + 1): x = i * major / (minor * (end - start)) v = i * major / minor m = i % minor == 0 screen = tuple(tuple(map(round, transform(x, area, offset))) for x in ((x, 0), (x, 1))) length = 12 if m else 6 (grid_major if m else grid_minor).append( svg.path( (transform(screen[0], (1, 1), (0.5, 0)), transform(screen[1], (1, 1), (0.5, -1))), classes = ('grid', 'grid-major' if m else 'grid-minor'))) ticks.append( svg.path( (transform(screen[1], (1, 1), (0.5, -8)), transform(screen[1], (1, 1), (0.5, -8 - length))), classes = ('tick',))) if m: labels.append(svg.text(str(round(v, 3)), position = transform(screen[1], (1, 1), (0, -16 - length)), classes = ('label-numeric', 'label-x') + (('unity',) if v == 1 else ()))) # title and subtitle if type(title) is str: screen = tuple(map(round, transform((0.5, 1), area, offset))) labels.append(svg.text(title, position = transform(screen, (1, 1), (0, -70)), classes = ('title',))) if type(subtitle) is str: screen = tuple(map(round, transform((0.5, 1), area, offset))) labels.append(svg.text(subtitle, position = transform(screen, (1, 1), (0, -50)), classes = ('subtitle',))) # plot data rows = tuple((name, ratio, ( margin_x[0] + area[0] * (ratio - range_x[0]) / (range_x[1] - range_x[0]), margin_y[1] + (i + 0.5) * 20)) for i, (name, ratio) in enumerate(sorted(ratios.items(), key = lambda k: k[1]))) # pixel coordinate of the y axis zero = margin_x[0] + area[0] * (1.0 - range_x[0]) / (range_x[1] - range_x[0]) legend = tuple(svg.text(name, (zero + 16 * (1 if ratio <= 1 else -1), screen[1]), classes = ('label-legend', 'better' if ratio <= 1 else 'worse')) for name, ratio, screen in rows) percents = tuple(svg.text('{:+.2f} %'.format((ratio - 1) * 100), (screen[0] - 16 * (1 if ratio <= 1 else -1), screen[1]), classes = ('label-percent', 'better' if ratio <= 1 else 'worse')) for name, ratio, screen in rows) stems = tuple(svg.path(( (zero, screen[1]), (screen[0] + 4 * (1 if ratio <= 1 else -1), screen[1])), classes = ('stem', 'better' if ratio <= 1 else 'worse')) for name, ratio, screen in rows if abs(screen[0] - zero) > 4) dots = tuple(svg.circle(screen, radius = 4, classes = ('dot', 'better' if ratio <= 1 else 'worse')) for name, ratio, screen in rows) style = ''' rect.background { fill: white; } path.grid { stroke-width: 1px; fill: none; } path.grid-major { stroke: #eeeeeeff; } path.grid-minor { stroke: #f5f5f5ff; } path.tick { stroke-width: 1px; stroke: #333333ff; fill: none; } path.stem { stroke-width: 1px; stroke-dasharray: 3 3; } circle.dot { stroke-width: 2px; stroke: #666; fill: none; } text { fill: #333333ff; font-family: 'SF Mono'; } text.label-numeric { font-size: 12px; } text.label-numeric.unity { font-weight: 700; } text.label-x { text-anchor: middle; dominant-baseline: text-top; } text.label-legend, text.label-percent { font-size: 12px; dominant-baseline: middle; } text.label-percent { font-weight: 700; } text.label-legend.better, text.label-percent.worse { text-anchor: begin; } text.label-legend.worse, text.label-percent.better { text-anchor: end; } text.title, text.subtitle { text-anchor: middle; } text.title { font-size: 20px; } text.subtitle { font-size: 12px; } ''' + ''' circle.better, path.stem.better {{ stroke: {color_fill_better} }} circle.worse, path.stem.worse {{ stroke: {color_fill_worse} }} text.label-percent.better {{ fill: {color_better} }} text.label-percent.worse {{ fill: {color_worse} }} '''.format( ** colors ) return svg.svg(display, style, tuple(grid_minor + grid_major + ticks + labels) + legend + percents + stems + dots)
def _generate_code(self): upperLeft = (0, 0) canvas = svg.IndentingStringIO("") x, y = upperLeft title_text = self.op.name logger.debug("generating code for operator: {}".format(title_text)) inputSize = self.getInputSize() outputSize = self.getOutputSize() child_ordering = {} for child in self.op.children: logger.debug("child with name: {}".format(child.name)) col = get_column_within_parent(child) if col not in child_ordering: child_ordering[col] = [] child_ordering[col].append(child) r = self.TitleHeight - 2 rect_x = upperLeft[0] + inputSize[0] rect_y = upperLeft[1] child_x = rect_x + r + self.PaddingForSlotName + self.PaddingBetweenInternalOps child_y = rect_y + 2 * r max_child_y = child_y max_child_x = child_x if len(self.op.children) > 0: if self.max_child_depth == 0: title_text += '*' # Asterisk in the title indicates that this operator has children that are not shown else: svgChildren = {} columnHeights = [] for col_index, col_children in sorted(child_ordering.items()): columnHeights.append(0) svgChildren[col_index] = [] for child in col_children: svgChild = SvgOperator(child, self.max_child_depth - 1) columnHeights[col_index] += svgChild.size()[1] svgChildren[col_index].append(svgChild) maxColumnHeight = max(columnHeights) columnExtraPadding = [] for col_index, col_svg_children in sorted(svgChildren.items()): columnExtraPadding.append(maxColumnHeight) for svgChild in col_svg_children: columnExtraPadding[col_index] -= svgChild.size()[1] for col_index, col_children in sorted(svgChildren.items()): for svgChild in col_children: child_y += (self.PaddingBetweenInternalOps + columnExtraPadding[col_index] / len(col_children)) / 2 svgChild.drawAt(canvas, (child_x, child_y)) lowerRight = (svgChild.size()[0] + child_x, svgChild.size()[1] + child_y) max_child_x = max(lowerRight[0], max_child_x) child_y = lowerRight[ 1] + self.PaddingBetweenInternalOps + columnExtraPadding[ col_index] / len(col_children) max_child_x += self.PaddingBetweenInternalOps max_child_y = max(max_child_y, child_y) child_x = max_child_x child_y = rect_y + 2 * r max_child_x += self.PaddingForSlotName + self.PaddingBetweenInternalOps def max_slot_name_length(slots): m = 0 for slot in slots: m = max(m, len(slot.name)) return m max_input_name = max_slot_name_length(self.op.inputs.values()) max_output_name = max_slot_name_length(self.op.outputs.values()) rect_width = max_child_x - rect_x rect_width = max(rect_width, 2 * self.PaddingBetweenInternalOps) rect_width = max(rect_width, 9 * len(self.op.name)) # Correct width depends on font... rect_width = max(rect_width, 9 * (max_input_name + max_output_name)) rect_width += r rect_height = max_child_y - rect_y rect_height = max(rect_height, outputSize[1]) rect_height = max(rect_height, inputSize[1]) rect_height += 2 * r rect_height = max(rect_height, 50) # Draw outer rectangle canvas += svg.rect(x=rect_x, y=rect_y, width=rect_width, height=rect_height, rx=r, ry=r, inkscape__connector_avoid="false", stroke='black', stroke_width=2, style='fill-opacity:0') path_d = 'M {startx} {y} L {endx} {y} Z'.format(startx=rect_x, y=rect_y + r + 2, endx=rect_x + rect_width) canvas += svg.path(d=path_d, stroke='black', stroke_width=1) block = partial(svg.tagblock, canvas) with block(svg.text, x=rect_x + rect_width / 2, y=rect_y + r, text_anchor='middle'): canvas += title_text + '\n' if self.op.debug_text: block = partial(svg.tagblock, canvas) with block(svg.text, x=rect_x + rect_width / 2, y=rect_y + 2 * r, text_anchor='middle'): canvas += self.op.debug_text + '\n' # Add extra padding between input slots if there's room (i.e. spread out the inputs to cover the entire left side) inputSlotPadding = (rect_height - self.getInputSize()[1]) / (len(self.inputs) + 1) # Draw inputs y += 1.5 * self.TitleHeight + inputSlotPadding for slot in self.inputs.values(): size = slot.size() slot_x, slot_y = (x + (inputSize[0] - size[0]), y) slot.drawAt(canvas, (slot_x, slot_y)) y += size[1] + inputSlotPadding text_x, text_y = (slot_x + size[0] + 5, slot_y + size[1] / 2) with block(svg.text, x=text_x, y=text_y, text_anchor='start'): canvas += slot.name + '\n' # Add extra padding between output slots if there's room (i.e. spread out the inputs to cover the entire right side) outputSlotPadding = (rect_height - self.getOutputSize()[1]) / (len(self.outputs) + 1) # Draw outputs x, y = upperLeft x += rect_width + inputSize[0] y += 1.5 * self.TitleHeight + outputSlotPadding for slot in self.outputs.values(): size = slot.size() text_x, text_y = (x - 5, y + size[1] / 2) slot.drawAt(canvas, (x, y)) y += size[1] + outputSlotPadding with block(svg.text, x=text_x, y=text_y, text_anchor='end'): canvas += slot.name + '\n' lowerRight_x = upperLeft[0] + rect_width + inputSize[0] + outputSize[0] lowerRight_y = upperLeft[1] + rect_height self._code = canvas return (lowerRight_x, lowerRight_y)
def _generate_code(self): upperLeft = (0,0) canvas = svg.IndentingStringIO("") x, y = upperLeft title_text = self.op.name logger.debug( "generating code for operator: {}".format( title_text ) ) inputSize = self.getInputSize() outputSize = self.getOutputSize() child_ordering = {} for child in self.op.children: logger.debug( "child with name: {}".format( child.name ) ) col = get_column_within_parent(child) if col not in child_ordering: child_ordering[col] = [] child_ordering[col].append(child) r = self.TitleHeight - 2 rect_x = upperLeft[0] + inputSize[0] rect_y = upperLeft[1] child_x = rect_x + r + self.PaddingForSlotName + self.PaddingBetweenInternalOps child_y = rect_y + 2*r max_child_y = child_y max_child_x = child_x if len(self.op.children) > 0: if self.max_child_depth == 0: title_text += '*' # Asterisk in the title indicates that this operator has children that are not shown else: svgChildren = {} columnHeights = [] for col_index, col_children in sorted( child_ordering.items() ): columnHeights.append(0) svgChildren[col_index] = [] for child in col_children: svgChild = SvgOperator(child, self.max_child_depth-1) columnHeights[col_index] += svgChild.size()[1] svgChildren[col_index].append(svgChild) maxColumnHeight = max(columnHeights) columnExtraPadding = [] for col_index, col_svg_children in sorted( svgChildren.items() ): columnExtraPadding.append( maxColumnHeight ) for svgChild in col_svg_children: columnExtraPadding[col_index] -= svgChild.size()[1] for col_index, col_children in sorted( svgChildren.items() ): for svgChild in col_children: child_y += (self.PaddingBetweenInternalOps + columnExtraPadding[col_index]/len(col_children)) / 2 svgChild.drawAt( canvas, (child_x, child_y) ) lowerRight = (svgChild.size()[0] + child_x, svgChild.size()[1] + child_y) max_child_x = max(lowerRight[0], max_child_x) child_y = lowerRight[1] + self.PaddingBetweenInternalOps + columnExtraPadding[col_index]/len(col_children) max_child_x += self.PaddingBetweenInternalOps max_child_y = max(max_child_y, child_y) child_x = max_child_x child_y = rect_y + 2*r max_child_x += self.PaddingForSlotName + self.PaddingBetweenInternalOps def max_slot_name_length(slots): m = 0 for slot in slots: m = max(m, len(slot.name)) return m max_input_name = max_slot_name_length(self.op.inputs.values()) max_output_name = max_slot_name_length(self.op.outputs.values()) rect_width = max_child_x - rect_x rect_width = max( rect_width, 2*self.PaddingBetweenInternalOps ) rect_width = max( rect_width, 9*len(self.op.name) ) # Correct width depends on font... rect_width = max( rect_width, 9*(max_input_name + max_output_name) ) rect_width += r rect_height = max_child_y - rect_y rect_height = max(rect_height, outputSize[1]) rect_height = max(rect_height, inputSize[1]) rect_height += 2*r rect_height = max( rect_height, 50 ) # Draw outer rectangle canvas += svg.rect(x=rect_x, y=rect_y, width=rect_width, height=rect_height, rx=r, ry=r, inkscape__connector_avoid="false", stroke='black', stroke_width=2, style='fill-opacity:0' ) path_d = 'M {startx} {y} L {endx} {y} Z'.format(startx=rect_x, y=rect_y+r+2, endx=rect_x+rect_width) canvas += svg.path(d=path_d, stroke='black', stroke_width=1) block = partial(svg.tagblock, canvas) with block(svg.text, x=rect_x+rect_width/2, y=rect_y+r, text_anchor='middle'): canvas += title_text + '\n' if self.op.debug_text: block = partial(svg.tagblock, canvas) with block(svg.text, x=rect_x+rect_width/2, y=rect_y+2*r, text_anchor='middle'): canvas += self.op.debug_text + '\n' # Add extra padding between input slots if there's room (i.e. spread out the inputs to cover the entire left side) inputSlotPadding = (rect_height - self.getInputSize()[1]) / (len(self.inputs)+1) # Draw inputs y += 1.5*self.TitleHeight + inputSlotPadding for slot in self.inputs.values(): size = slot.size() slot_x, slot_y = (x+(inputSize[0]-size[0]),y) slot.drawAt( canvas, (slot_x, slot_y) ) y += size[1] + inputSlotPadding text_x, text_y = (slot_x + size[0] + 5, slot_y + size[1]/2) with block(svg.text, x=text_x, y=text_y, text_anchor='start'): canvas += slot.name + '\n' # Add extra padding between output slots if there's room (i.e. spread out the inputs to cover the entire right side) outputSlotPadding = (rect_height - self.getOutputSize()[1]) / (len(self.outputs)+1) # Draw outputs x, y = upperLeft x += rect_width + inputSize[0] y += 1.5*self.TitleHeight + outputSlotPadding for slot in self.outputs.values(): size = slot.size() text_x, text_y = (x - 5, y + size[1]/2) slot.drawAt( canvas, (x,y) ) y += size[1] + outputSlotPadding with block(svg.text, x=text_x, y=text_y, text_anchor='end'): canvas += slot.name + '\n' lowerRight_x = upperLeft[0] + rect_width + inputSize[0] + outputSize[0] lowerRight_y = upperLeft[1] + rect_height self._code = canvas return (lowerRight_x, lowerRight_y)
def makemagnitudelegend(): angles = [-math.pi / 2, math.pi / 2] wedgeangle = math.pi * 2 / 21 out = svg.svg(width=250, height=1000, viewbox='0 0 250 1000') x = (500 + math.cos(angles[0]) * c.textradius) y = (500 + math.sin(angles[0]) * c.textradius) if c.swapsaliencemagnitude: te = 'Salience:' else: te = 'Magnitude:' out.add( svg.text(te, 125, 25, fontsize=c.font, p='style="text-anchor: middle; dominant-baseline: middle"')) for angle in angles: x1 = (125 + math.cos(angle + wedgeangle / 2) * c.centerradius) y1 = (500 + math.sin(angle + wedgeangle / 2) * c.centerradius) x2 = (125 + math.cos(angle + wedgeangle / 2) * c.textradius) y2 = (500 + math.sin(angle + wedgeangle / 2) * c.textradius) x3 = (125 + math.cos(angle - wedgeangle / 2) * c.textradius) y3 = (500 + math.sin(angle - wedgeangle / 2) * c.textradius) x4 = (125 + math.cos(angle - wedgeangle / 2) * c.centerradius) y4 = (500 + math.sin(angle - wedgeangle / 2) * c.centerradius) out.add(svg.line(x1, y1, x2, y2, 'black', 2)) out.add(svg.line(x3, y3, x4, y4, 'black', 2)) if (c.drawsaliencedividers): x1 = (125 + math.cos(angle) * c.centerradius) y1 = (500 + math.sin(angle) * c.centerradius) x2 = (125 + math.cos(angle) * c.edgeradius) y2 = (500 + math.sin(angle) * c.edgeradius) out.add(svg.line(x1, y1, x2, y2, 'black', .5)) for j in range(1 - c.includezerosalience, 3): if (c.saliencebywidth > 1): wedgewidth = wedgeangle / 2 / (c.saliencebywidth** 3) * (c.saliencebywidth**j) else: wedgewidth = wedgeangle / 2 / ( 3 + c.includezerosalience) * (j + c.includezerosalience) x1 = (125 + math.cos(angle - wedgewidth) * c.centerradius) y1 = (500 + math.sin(angle - wedgewidth) * c.centerradius) x2 = (125 + math.cos(angle - wedgewidth) * c.edgeradius) y2 = (500 + math.sin(angle - wedgewidth) * c.edgeradius) out.add(svg.line(x1, y1, x2, y2, 'black', .5)) x1 = (125 + math.cos(angle + wedgewidth) * c.centerradius) y1 = (500 + math.sin(angle + wedgewidth) * c.centerradius) x2 = (125 + math.cos(angle + wedgewidth) * c.edgeradius) y2 = (500 + math.sin(angle + wedgewidth) * c.edgeradius) out.add(svg.line(x1, y1, x2, y2, 'black', .5)) for i in range(0, c.maxvalue + c.includezeromagnitude + 1): if (i == c.includezeromagnitude): w = 5 else: w = 1 r = ringradii(i) x1 = (125 + math.cos(angle + wedgeangle / 1.5) * r) y1 = (500 + math.sin(angle + wedgeangle / 1.5) * r) x2 = (125 + math.cos(angle - wedgeangle / 1.5) * r) y2 = (500 + math.sin(angle - wedgeangle / 1.5) * r) d = 'M %s,%s A %s,%s 0 0,0 %s,%s' % (x1, y1, r, r, x2, y2) out.add(svg.path(d, stroke='black', strokewidth=w)) y = y1 if (i % 2 == 0): x = x2 + 10 * angle else: x = x1 - 10 * angle if (i - c.includezeromagnitude >= 0): out.add( svg.text( i - c.includezeromagnitude, x, y, fontsize=c.font, p='style="text-anchor: middle; dominant-baseline: middle"' )) return out
def makecircle(magnitude, salience, benefit=1): if c.swapsaliencemagnitude: tm = salience[:] salience = magnitude[:] magnitude = tm #general variables indicatorseparatorangles = [ -math.pi * 2 / 21 * i + math.pi / 21 for i in range(0, 22) ] indicatorcenterangles = [-math.pi * 2 / 21 * i for i in range(0, 21)] wedgeangle = math.pi * 2 / 21 out = svg.svg(width=1000, height=1000 + 100 * c.saliencelegend, viewbox='0 0 1000 1%d00' % (1 * c.saliencelegend == True)) if (benefit): colors = c.colorsbenefit else: colors = c.colorscost if c.centerlabel is not None: out.add( svg.text( c.centerlabel[1 - benefit], 500, 500, fontsize=c.font, p='style="text-anchor: middle; dominant-baseline: middle"')) #draw wedges for i in range(0, 21): r = ringradii(magnitude[i] + c.includezeromagnitude) if (c.saliencebywidth == 1): wedgewidth = wedgeangle / 2 / (3 + c.includezerosalience) * ( salience[i] + c.includezerosalience) elif (c.saliencebywidth > 1): wedgewidth = wedgeangle / 2 / (saliencebywidth**3) * ( c.saliencebywidth**salience[i]) else: wedgewidth = wedgeangle / 2 x1 = (500 + math.cos(indicatorcenterangles[i] + wedgewidth) * c.centerradius) y1 = (500 + math.sin(indicatorcenterangles[i] + wedgewidth) * c.centerradius) x2 = (500 + math.cos(indicatorcenterangles[i] + wedgewidth) * r) y2 = (500 + math.sin(indicatorcenterangles[i] + wedgewidth) * r) x3 = (500 + math.cos(indicatorcenterangles[i] - wedgewidth) * r) y3 = (500 + math.sin(indicatorcenterangles[i] - wedgewidth) * r) x4 = (500 + math.cos(indicatorcenterangles[i] - wedgewidth) * c.centerradius) y4 = (500 + math.sin(indicatorcenterangles[i] - wedgewidth) * c.centerradius) if (c.saliencebycolor): s = ((salience[i] + c.includezerosalience)**c.saliencebycolor) / ( (3.0 + c.includezerosalience)**c.saliencebycolor) else: s = 1 red, green, blue = colors[i // 7] d = 'M %s,%s L %s,%s A %s,%s 0 0,0 %s,%s L %s,%s A %s,%s 0 0,1 %s,%s' % ( x1, y1, x2, y2, r, r, x3, y3, x4, y4, c.centerradius, c.centerradius, x1, y1) if (salience[i] > 0 or c.includezerosalience): out.add( svg.path(d, fill='rgb(%s,%s,%s)' % (red, green, blue), p='fill-opacity="%s"' % s)) #draw dividers and text for i in range(0, 21): if (c.saliencebywidth and c.drawsaliencedividers): x1 = (500 + math.cos(indicatorcenterangles[i]) * c.centerradius) y1 = (500 + math.sin(indicatorcenterangles[i]) * c.centerradius) x2 = (500 + math.cos(indicatorcenterangles[i]) * c.edgeradius) y2 = (500 + math.sin(indicatorcenterangles[i]) * c.edgeradius) out.add(svg.line(x1, y1, x2, y2, 'black', .5)) for j in range(1 - c.includezerosalience, 3): if (c.saliencebywidth > 1): wedgewidth = wedgeangle / 2 / (c.saliencebywidth** 3) * (c.saliencebywidth**j) else: wedgewidth = wedgeangle / 2 / ( 3 + c.includezerosalience) * (j + c.includezerosalience) for k in [1, -1]: x1 = (500 + math.cos(indicatorcenterangles[i] + wedgewidth * k) * c.centerradius) y1 = (500 + math.sin(indicatorcenterangles[i] + wedgewidth * k) * c.centerradius) x2 = (500 + math.cos(indicatorcenterangles[i] + wedgewidth * k) * c.edgeradius) y2 = (500 + math.sin(indicatorcenterangles[i] + wedgewidth * k) * c.edgeradius) out.add(svg.line(x1, y1, x2, y2, 'black', .5)) #invisible link and tooltip box x1 = (500 + math.cos(indicatorcenterangles[i] + wedgeangle / 2) * c.centerradius) y1 = (500 + math.sin(indicatorcenterangles[i] + wedgeangle / 2) * c.centerradius) x2 = (500 + math.cos(indicatorcenterangles[i] + wedgeangle / 2) * c.textradius + 25) y2 = (500 + math.sin(indicatorcenterangles[i] + wedgeangle / 2) * c.textradius + 25) x3 = (500 + math.cos(indicatorcenterangles[i] - wedgeangle / 2) * c.textradius + 25) y3 = (500 + math.sin(indicatorcenterangles[i] - wedgeangle / 2) * c.textradius + 25) x4 = (500 + math.cos(indicatorcenterangles[i] - wedgeangle / 2) * c.centerradius) y4 = (500 + math.sin(indicatorcenterangles[i] - wedgeangle / 2) * c.centerradius) d = 'M %s,%s L %s,%s L %s,%s L %s,%s z' % (x1, y1, x2, y2, x3, y3, x4, y4) newpath = svg.path(d, fill='white', p='fill-opacity="0.0"') newpath.add( svg.title(' %s: %s\n Magnitude %s\tSalience %s' % (c.indicatornames[i], c.indicatorfullnames[i], magnitude[i], salience[i]))) out.add(newpath) x = (500 + math.cos(indicatorcenterangles[i]) * c.textradius) y = (500 + math.sin(indicatorcenterangles[i]) * c.textradius) out.add( svg.text( c.indicatornames[i], x, y, fontsize=c.font, p='style="text-anchor: middle; dominant-baseline: middle"')) # draw dividers x1 = 500 + math.cos(indicatorseparatorangles[i]) * c.centerradius y1 = 500 + math.sin(indicatorseparatorangles[i]) * c.centerradius if (i % 7 == 0): x2 = 500 + math.cos( indicatorseparatorangles[i]) * (c.textradius + 25) y2 = 500 + math.sin( indicatorseparatorangles[i]) * (c.textradius + 25) out.add(svg.line(x1, y1, x2, y2, 'black', 10)) elif (c.xgrid or (c.saliencebywidth and c.drawsaliencedividers)): x2 = 500 + math.cos(indicatorseparatorangles[i]) * (c.textradius) y2 = 500 + math.sin(indicatorseparatorangles[i]) * (c.textradius) out.add(svg.line(x1, y1, x2, y2, 'black', 2)) #draw rings for i in range(0, c.maxvalue + c.includezeromagnitude + 1): if (i == c.includezeromagnitude): w = 5 out.add(svg.circle('500', '500', ringradii(i), 'black', w, 'none')) elif (c.ygrid or i == 0): w = 1 out.add(svg.circle('500', '500', ringradii(i), 'black', w, 'none')) return out