def draw_all_shapes(): """ Quick demo of creating SVG object, using all methods, and saving the finished file. """ s = svg.SVG() s.create(256, 192) s.fill("#A0A0FF") s.circle("#000080", 4, "#0000FF", 32, 64, 96) s.line("#000000", 2, 8, 8, 248, 184) s.rectangle(64, 64, 112, 32, "#00FF00", "#008000", 4, 4, 4) s.text(32, 16, "sans-serif", 16, "#000000", "#000000", "codedrome.com") s.ellipse(64, 160, 32, 16, "#FF0000", "#800000", 4) s.finalize() try: s.save("allshapes.svg") except IOError as ioe: print(ioe) print(s)
def svg(self): Fig.svg(self) output = self._svg self._svg = svg.SVG("svg", self.width, self.height, [0, 0, self.width, self.height]) self._svg.__dict__["children"] = output.children self._svg.__dict__["attrib"].update(output.attrib)
def draw_all_shapes(): s = svg.SVG() s.create(670, 430) s.fill("#00022e") for star in range(0, 800): x = random.randrange(0, 800) y = random.randrange(0, 600) s.rectangle(1, 1, x, y, "silver", "silver", 1, 1, 1) s.text(80, 178, "script", 50, "#FFFF00", "#000000", "weet") s.text(50, 240, "script", 160, "#DC143C", "#000000", "Sensation...") s.finalize() try: s.save("assessment.svg") except IOError as ioe: print(ioe) print(s)
def draw_all_shapes(): """ Quick demo of creating SVG object, using all methods, and saving the finished file. """ s = svg.SVG() s.create(256, 192) s.fill("#A0A0FF") s.circle("#000080", 4, "#0000FF", 32, 64, 96) s.line("#000000", 2, 8, 8, 248, 184) s.rectangle(64, 64, 112, 32, "#00FF00", "#008000", 4, 4, 4) s.text(32, 16, "sans-serif", 16, "#000000", "#000000", "Merry Christmas codedrome.com from Alex Pedersen") s.ellipse(64, 160, 32, 16, "#FF0000", "#800000", 4) d = ('M' + ' ' + str(120) + ' ' + str(150) + ',' + ' ' + 'C' + ' ' + str(110) + ' ' + str(80) + ' ' + str(110) + ' ' + str(80) + ',' + ' ' + str(220) + ' ' + str(190)) s.path("white", "white", 2, d) s.finalize() try: s.save("allshapes.svg") except IOError as ioe: print(ioe) print(s)
def _render_text(self, X, Y, angle, text): text_attrib = {"transform": "translate(%g, %g) rotate(%g)" % (X + self.text_offsetx*math.cos(angle) - self.text_offsety*math.sin(angle), Y + self.text_offsetx*math.sin(angle) + self.text_offsety*math.cos(angle), 180./math.pi*angle), "text-anchor": "middle"} text_attrib.update(self.text_attrib) return svg.SVG("text", 0., 0., **text_attrib)(text)
def renderpoem(poem, scale=60): r = radius(len(poem)) + 0.3 s = svg.SVG( width=2 * r * scale, height=2 * r * scale, #viewBox='-50 -50 100 100', stroke='black', fill='none', stroke_width=2) g = svg.Group(transform='translate(%.2f,%.2f)' % (r * scale, r * scale)) s.append(g) g2 = svg.Group(transform='scale(8)', stroke='lightgrey') g.append(g2) for row, line in enumerate(poem): r = radius(row) offset = 0.5 + row * 1.618 for pos, word in enumerate(line): theta = (pos - 0.5 + offset % 1) * (360 / len(line)) - 90 x = scale * r * math.cos(math.radians(theta)) y = scale * r * math.sin(math.radians(theta)) g.append(makeglyph(word, x, y, theta, label=False)) return s
def mondrian(): bancs=[[0,1,2],[0,2,1],[2,0,1],[2,1,0],[1,2,0],[1,0,2]] inicio_zona_clock_x=-8*0.3333333333 inicio_zona_clock_y=-6*0.333333 posicaoinicialx_circuito=1 posicaoinicialy_circuito=2 cores_zona_clock=["white", "#bebebe", "#565656"] cores_clock=["#0cf60c", "#0405f2", "#f408f4"] escala=100 a=0 s = svg.SVG() with open('c17withoutcells') as json_file: data = json.load(json_file) for p in data: if a==0: s.create(int(p['numberX'])*escala*3, int(p['numberY'])*escala*6) s.fill("white") s.rectangle(int(p['numberX'])*escala, int(p['numberY'])*escala, 0, 0, "white", "black", 1, 0, 0) for i in range(10): for j in range(10): for k in range(6): for l in range(3): s.rectangle(escala*3, (escala*2)*3, (inicio_zona_clock_x*3+j+l)*(escala*3)+(escala*6*j), (inicio_zona_clock_y*6+i+k)*((escala*2)*3)+(escala*6*5*i), cores_zona_clock[bancs[k][l]], "black", 0, 0, 0) a=1 else: if(str(p['logic'])=="cross"): s.rectangle(escala, (escala), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito), (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+escala/2, cores_clock[int(p['clock_zone'])], cores_clock[int(p['clock_zone'])], 0, 0, 0) s.line("black", (escala/8), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito), (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+escala/2, (int(p['x'])*escala)+(escala*posicaoinicialx_circuito)+escala, (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+escala/2) s.line("black", (escala/8), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito), (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+escala/2, (int(p['x'])*escala)+(escala*posicaoinicialx_circuito), (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+escala/2+(escala)) s.line("black", (escala/8), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito), (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+escala/2+(escala), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito)+escala, (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+escala/2+(escala)) s.line("black", (escala/8), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito)+escala, (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+escala/2+(escala), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito)+escala, (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+escala/2) else: s.rectangle(escala, (escala*2), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito), (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2), cores_clock[int(p['clock_zone'])], cores_clock[int(p['clock_zone'])], 0, 0, 0) s.line("black", (escala/8), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito), (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito)+escala, (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)) s.line("black", (escala/8), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito), (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito), (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+(escala*2)) s.line("black", (escala/8), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito), (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+(escala*2), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito)+escala, (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+(escala*2)) s.line("black", (escala/8), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito)+escala, (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)+(escala*2), (int(p['x'])*escala)+(escala*posicaoinicialx_circuito)+escala, (int(p['y'])*(escala*2))+(escala*posicaoinicialy_circuito*2)) if(p['type']!="regular"): s.text((int(p['x'])*escala)+(escala*posicaoinicialx_circuito)+(escala/7), (int(p['y'])*(escala*2)+(escala*posicaoinicialy_circuito*2)+escala), "sans-serif", escala/1.5, "#FFFFFF", "#000000", str(p['id'])) print('fixed_magnetization: ' + str(p['fixed_magnetization'])) s.finalize() try: s.save("c17withoutcells.svg") except IOError as ioe: print(ioe)
def createSvgNode(self): svgFile = svg.SVG() svgRoot = svgFile.getSvg() subsystemNode = svgFile.getSubsystemZoomNode(self.subsystemName) if subsystemNode != None: self.drawDeviceIcon(subsystemNode) if SettingsCloud.getParameter("deviceCaptions") == True: self.drawDeviceCaption(subsystemNode) else: print "Device " + self.name + " can not be added - wrong subsystem name"
def renderglyph(word, scale=60): s = svg.SVG(width=scale * 1.2, height=scale * 1.2, stroke='black', fill='none', stroke_width=2) g = svg.Group(transform='translate(%.2f,%.2f)' % (scale * 0.6, scale * 0.6)) s.append(g) g.append(makeglyph(word, 0, 0, -90, label=False)) return s
def svg(self): if (self.xmin is not None and self.xmax is not None and self.ymin is not None and self.ymax is not None): self.trans = trans.window( self.xmin, self.xmax, self.ymin, self.ymax, x=self.x, y=self.y, width=self.width, height=self.height, xlogbase=self.xlogbase, ylogbase=self.ylogbase, minusInfinityX=(self.x - 10. * self.width), minusInfinityY=(self.y - 10. * self.height), flipx=self.flipx, flipy=self.flipy) else: self.fit() self._svg = new.instance(svg.SVG) self._svg.__dict__["tag"] = "g" self._svg.__dict__["attrib"] = self.attrib self._svg.__dict__["_svg"] = self._svg self._svg.__dict__["children"] = [] for child in self.children: self._svg.__dict__["children"].append( trans.transform(self.trans, child)) if self.clip: clipPath = svg.SVG("clipPath", id=svg.randomid("clip-"))(svg.SVG( "rect", self.x, self.y, self.width, self.height)) self._svg["clip-path"] = "url(#%s)" % clipPath["id"] self._svg = svg.SVG("g", clipPath, self._svg)
def updateSvg(self): if self.isCorrect() == False: print("Warning: icon's path is invalid!") svgFile = svg.SVG() self.svgRoot = svgFile.getSvg() symbolsNode = svgFile.getSymbolsNode() gElement = etree.SubElement(symbolsNode, "g") gElement.attrib["style"] = "display:inline" gElement.attrib["id"] = self.name imgElement = etree.SubElement(gElement, "image") imgElement.attrib["{http://www.w3.org/1999/xlink}href"] = self.path imgElement.attrib["id"] = self.name + "Group" imgElement.attrib["x"] = str(self.coordinates[0]) imgElement.attrib["y"] = str(self.coordinates[1]) imgElement.attrib["width"] = "30" imgElement.attrib["height"] = "30"
def svg(self): obj = new.instance(svg.SVG) obj.__dict__["tag"] = "path" obj.__dict__["attrib"] = self.attrib obj.__dict__["children"] = self.children obj.__dict__["_svg"] = obj obj.attrib["d"] = self.d() if self.marks == []: output = obj else: output = svg.SVG("g", obj) lowX, lowY = self(self.low) highX, highY = self(self.high) for item in self.marks: if isinstance(item, (int, long, float)): t, mark = item, glyphs.tick else: t, mark = item # marks should be (pos, mark) pairs or just pos X, Y = self(t) if (self.low <= t <= self.high or math.sqrt((X - lowX)**2 + (Y - lowY)**2) < trans.epsilon or math.sqrt((X - highX)**2 + (Y - highY)**2) < trans.epsilon): angle = self.angle(t) if isinstance(mark, basestring): mark = self._render_text(X, Y, angle, mark) else: mark = trans.transform( lambda x, y: (X + math.cos(angle) * x - math.sin(angle) * y, Y + math.sin(angle) * x + math.cos(angle) * y), mark) output.append(mark) self._svg = output
def i_want_to_believe(): """ A more complex drawing for X Files fans. """ s = svg.SVG() s.create(512, 768) s.fill("#000010") for star in range(0, 512): x = random.randrange(0, 512) y = random.randrange(0, 768) s.rectangle(1, 1, x, y, "white", "white", 0, 0, 0) s.text(96, 712, "sans-serif", 32, "#FFFFFF", "#FFFFFF", "I WANT TO BELIEVE") s.circle("silver", 1, "rgba(0,0,0,0)", 28, 256, 384) s.ellipse(256, 374, 8, 14, "#808080", "#808080", 0) s.ellipse(252, 372, 3, 2, "#000000", "#000000", 0) s.ellipse(260, 372, 3, 2, "#000000", "#000000", 0) s.rectangle(1, 1, 251, 371, "white", "white", 0, 0, 0) s.rectangle(1, 1, 259, 371, "white", "white", 0, 0, 0) s.line("black", 2, 254, 378, 258, 378) s.line("silver", 2, 234, 416, 226, 432) s.line("silver", 2, 278, 416, 286, 432) s.ellipse(256, 400, 64, 16, "silver", "silver", 4) s.finalize() try: s.save("iwanttobelieve.svg") except IOError as ioe: print(ioe)
def mondrian(): """ Serious art here. """ s = svg.SVG() s.create(512, 512) s.fill("white") s.rectangle(512, 512, 0, 0, "white", "black", 1, 0, 0) s.rectangle(256, 256, 64, 64, "red", "red", 0, 0, 0) s.rectangle(128, 128, 64, 320, "black", "black", 0, 0, 0) s.rectangle(64, 128, 0, 384, "orange", "orange", 0, 0, 0) s.rectangle(128, 192, 320, 0, "orange", "orange", 0, 0, 0) s.rectangle(128, 64, 320, 384, "navy", "navy", 0, 0, 0) s.rectangle(64, 128, 448, 384, "red", "red", 0, 0, 0) s.line("black", 8, 0, 64, 448, 64) s.line("black", 8, 64, 64, 64, 512) s.line("black", 8, 0, 192, 64, 192) s.line("black", 8, 0, 384, 512, 384) s.line("black", 8, 128, 0, 128, 64) s.line("black", 8, 320, 0, 320, 448) s.line("black", 8, 64, 320, 448, 320) s.line("black", 8, 320, 192, 448, 192) s.line("black", 8, 64, 448, 448, 448) s.line("black", 8, 448, 0, 448, 512) s.line("black", 8, 192, 320, 192, 512) s.line("black", 8, 384, 192, 384, 320) s.finalize() try: s.save("mondrian.svg") except IOError as ioe: print(ioe)
def func_image_svg_plus_xml(request, cf): __argument = request.GET.copy() try: convert = mimetypes.guess_extension( __argument.get("force_mimetype", "").strip()).split(".")[1] except: convert = None if convert and convert in ("png", ): try: s = svg.SVG(cf) output = s.render( outputtype=convert, width=__argument.get("width"), height=__argument.get("height"), ) tmp = func_image(request, output) return tmp except: return cf return cf
def sketch(thing, outname): print outname, sys.stdout.flush() ox = 0 oy = 0 pic = svg.SVG() pic.require(0, 0) triangles = thing.triangles() def rot(triangles, x, y, z, angle): mat = shape.rotation_matrix(x, y, z, angle) return [[shape.transform_point_3(mat, item2) for item2 in item] for item in triangles] def iterator(): #yield thing, 1 yield triangles, 1 #item_rot = thing.copy() #item_rot.rotate(1,0,0,-90) #yield item_rot, 1 #del item_rot yield rot(triangles, 1, 0, 0, -90), 1 #item_iso = thing.copy() #item_iso.rotate(0,0,1,-45, 256) #item_iso.rotate(1,0,0,-45, 256) #yield item_iso, 0 #del item_iso yield rot(rot(triangles, 0, 0, 1, -45), 1, 0, 0, -45), 0 # for (item,showdim) in iterator(): # extent = item.extent() for (this_triangles, showdim) in iterator(): extent = shape.extent_3(item2 for item in this_triangles for item2 in item) if extent.xmax - extent.xmin < extent.ymax - extent.ymin: ox = pic.max_x + 10 oy = -pic.max_y else: ox = 0.0 oy = -(extent.ymax - extent.ymin) - pic.max_y - 20 ox -= extent.xmin oy -= extent.ymin xmid = (extent.xmin + extent.xmax) * 0.5 ymid = (extent.ymin + extent.ymax) * 0.5 zmid = (extent.zmin + extent.zmax) * 0.5 if showdim: pic.text(ox + xmid, -oy - extent.ymax - 10, '%.1fmm' % (extent.xmax - extent.xmin)) pic.text(ox + extent.xmax + 5, -oy - ymid, '%.1fmm' % (extent.ymax - extent.ymin)) lines = collections.defaultdict(list) for tri in this_triangles: #a = numpy.array(tri) #normal = numpy.cross(a[1]-a[0],a[2]-a[0]) normal = cross(sub(tri[1], tri[0]), sub(tri[2], tri[0])) length = math.sqrt(normal[0]**2 + normal[1]**2 + normal[2]**2) normal = (normal[0] / length, normal[1] / length, normal[2] / length) lines[(tri[0], tri[1])].append(normal) lines[(tri[1], tri[2])].append(normal) lines[(tri[2], tri[0])].append(normal) for a, b in lines: if (b, a) not in lines: weight = -1.0 normals = lines[(a, b)] else: if (b, a) < (a, b): continue normals = lines[(a, b)] + lines[(b, a)] weight = -1.0 for n1 in lines[(a, b)]: for n2 in lines[(b, a)]: if n1[2] * n2[2] > 0.0: weight = max(weight, dot(n1, n2)) weight = (1.0 - weight) * 0.5 if weight < 0.01: continue weight = min(1.0, weight * 2) outs = 0 ins = 0 for n in normals: if n[2] <= 1e-6: ins += 1 if n[2] >= -1e-6: outs += 1 if ins >= 2 and not outs: weight *= 0.25 #elif outs >= 2 and not ins: # weight *= 2.0 pic.line([(ox + x, -oy - y) for x, y, z in [a, b]], width=0.2 * weight) del lines pic.save(outname) print
### standard glyphs, may be modifed at runtime by importing glyphs import svg # don't use glyphs in anything that gets imported into svg.py! # things that get attached to Curves as marks should assume that the line is horizontal, points to the right, and passes through 0 # these marks are effectively like Pins at (0,0) farrowhead = svg.SVG("path", "M0 0L-0.5 -1.2 3 0 -0.5 1.2 0 0Z", stroke="none", fill="black") farrowhead.repr = "<farrowhead>" barrowhead = svg.SVG("path", "M0 0L0.5 -1.2 -3 0 0.5 1.2 0 0Z", stroke="none", fill="black") barrowhead.repr = "<barrowhead>" tick = svg.SVG("path", "M0 -1.5L0 1.5") tick.repr = "<tick>" minitick = svg.SVG("path", "M0 -0.75L0 0.75") minitick.repr = "<minitick>" frtick = svg.SVG("path", "M0 0L0 1.5") frtick.repr = "<frtick>" frminitick = svg.SVG("path", "M0 0L0 0.75") frminitick.repr = "<frminitick>"
def taylor_sin_plot(maxsin, maxdegrees, step, width, height, filename): """ Plots a sine wave using Python's math.sin and then plots sine waves using the taylorseries module to various degrees to illustrate increasing accurancy. Plots are generated and saved using the svg module. """ topmargin = 64 bottommargin = 32 leftmargin = 32 rightmargin = 128 graph_height = height - topmargin - bottommargin graph_width = width - leftmargin - rightmargin pixels_per_unit_x = graph_width / maxdegrees pixels_per_unit_y = graph_height / (maxsin * 2.0) yzero = topmargin + (graph_height / 2) colours = ("blue", "red", "orange", "purple", "green", "cyan") # Create svg object s = svg.SVG() s.create(width, height) s.fill("#FFFFFF") # header text and border lines s.text( leftmargin, 38, "sans-serif", 16, "#000000", "#000000", "start", "Sines calculated with Taylor Polynomials to degree 3, 5, 7, 9 and 11") s.line("#808080", 2, leftmargin, topmargin, leftmargin, height - bottommargin) s.line("#808080", 2, leftmargin, height - bottommargin, width - rightmargin, height - bottommargin) # y axis indexes and values y = topmargin for i in range(maxsin, (maxsin * -1) - 1, -1): s.line("#808080", 1, leftmargin - 8, y, width - rightmargin, y) s.text(20, y + 4, "sans-serif", 12, "#000000", "#000000", "end", str(i)) y += pixels_per_unit_y # x axis indexes and values x = leftmargin for d in range(0, maxdegrees + 1, 90): s.line("#808080", 1, x, topmargin, x, height - bottommargin + 8) s.text(x, height - bottommargin + 24, "sans-serif", 12, "#000000", "#000000", "middle", str(d)) x += (pixels_per_unit_x * 90) # key x = width - rightmargin + 16 y = topmargin + 16 currdegree = 3 for colourindex in range(0, 6): s.circle(colours[colourindex], 0, colours[colourindex], 6, x, y) if (colourindex == 0): s.text(x + 16, y + 4, "sans-serif", 12, "#000000", "#000000", "start", "math.sin") else: s.text(x + 16, y + 4, "sans-serif", 12, "#000000", "#000000", "start", str(currdegree)) currdegree += 2 y += 24 # Taylor Series plots x = leftmargin for degree in range(0, maxdegrees + 1, step): radians = math.radians(degree) sine = math.sin(radians) y = yzero - (sine * pixels_per_unit_y) colourindex = 0 s.circle(colours[colourindex], 0, colours[colourindex], 3, x, y) for poly_degree in range(3, 12, 2): colourindex += 1 sine = taylorseries.sine_of_radians(radians, poly_degree) if (sine <= maxsin and sine >= (maxsin * -1)): y = yzero - (sine * pixels_per_unit_y) s.circle(colours[colourindex], 0, colours[colourindex], 3, x, y) x += pixels_per_unit_x * step s.finalize() s.save(filename) print("File saved")
def _save(self, state_vec, other_vecs=[]): self.state_vec = state_vec self.instrument = self.unpack(state_vec) with open(os.path.join(self.output_dir, 'data.pickle'), 'wb') as f: if sys.version_info.major == 3: pickle.dump(self, f, fix_imports=True) else: pickle.dump(self, f) patched_instrument = self.patch_instrument(self.instrument) patched_instrument.prepare() patched_instrument.prepare_phase() # #any_extra = any( item != 0.0 for item in self.hole_extra_height_by_diameter ) # #if any_extra: # #TODO: implement embextra using patch_instrument # mod_instrument = self.unpack( state_vec ) # #mod_instrument.hole_extra_height_by_diameter = [ 0.0 ] * len(self.hole_extra_height_by_diameter) # mod_instrument.hole_lengths = [ # (mod_instrument.outer(mod_instrument.hole_positions[i]) # - mod_instrument.inner(mod_instrument.hole_positions[i])) * 0.5 # for i in range(self.n_holes) # ] # mod_instrument.prepare() diagram = svg.SVG() for vec in random.sample(other_vecs, min(20, len(other_vecs))): self._draw(diagram, vec, '#aaaaaa', '#ffaaaa') self._draw(diagram, state_vec) #for i in range(self.n_holes): # diagram.circle(0.0, -self.instrument.inner_hole_positions[i], self.instrument.hole_diameters[i], # '#ff0000') # diagram.circle(0.0, -self.instrument.hole_positions[i], self.instrument.hole_diameters[i]) #diagram.profile(self.instrument.outer) #diagram.profile(self.instrument.stepped_inner) # #if self.closed_top: # d = self.instrument.stepped_inner(self.instrument.length) # diagram.line([(-0.5*d,-self.instrument.length),(0.5*d,-self.instrument.length)]) text_x = diagram.max_x * 1.25 text_y = 0 for i in range(self.n_holes): this_y = min(text_y, -self.instrument.hole_positions[i]) text_y = diagram.text(text_x, this_y, '%.1fmm' % self.instrument.hole_diameters[i]) diagram.text(text_x + 90.0, this_y, 'at %.1fmm' % self.instrument.hole_positions[i]) if i < self.n_holes - 1: this_y = min( text_y, -0.5 * (self.instrument.hole_positions[i] + self.instrument.hole_positions[i + 1])) #text_y = diagram.text( text_x + 45.0, this_y, '%.1fmm' % (self.instrument.hole_positions[i + 1] - self.instrument.hole_positions[i])) diagram.text(text_x + 90.0, min(text_y, -self.instrument.length), '%.1fmm' % self.instrument.length) text_x = diagram.max_x graph_x = text_x + 200 emit_x = graph_x + 220 text_y = 0 for item in self.fingerings: note = item[0] fingers = item[1] w1 = wavelength(note, self.transpose) if len(item) < 3: w2 = patched_instrument.true_wavelength_near(w1, fingers) else: w2 = patched_instrument.true_nth_wavelength_near( w1, fingers, item[2]) cents = int(round(log2(w2 / w1) * 1200.0)) n_probes = 301 max_cents = 2400.0 width = 200.0 step = pow(0.5, max_cents / ((n_probes - 1) * 0.5 * 1200.0)) low = w1 * pow(step, -(n_probes - 1) / 2.0) probes = [low * pow(step, i) for i in range(n_probes)] #scores = [ patched_instrument.resonance_score(probe, fingers) for probe in probes ] # #points = [ (graph_x+i*width/n_probes,text_y-score*7.0) # for i,score in enumerate(scores) ] #for i in range(len(probes)-1): # if scores[i] > 0 and scores[i+1] < 0: continue # diagram.line(points[i:i+2], '#000000', 0.2) scores = [ patched_instrument.resonance_phase(probe, fingers) for probe in probes ] points = [(graph_x + i * width / n_probes, text_y - (((score + 0.5) % 1.0) - 0.5) * 14.0) for i, score in enumerate(scores)] for i in range(len(probes) - 1): c = math.floor(scores[i] + 0.5) if c != math.floor(scores[i + 1] + 0.5): continue r, g, b = [ int((math.cos( (c / 5.0 + offset) * math.pi * 2.0) * 0.5 + 0.5) * 200) for offset in [0.0, 1.0 / 3, 2.0 / 3] ] diagram.line(points[i:i + 2], '#%02x%02x%02x' % (r, g, b), 0.2) diagram.line([(graph_x + width * 0.5, text_y + 7), (graph_x + width * 0.5, text_y - 7)], '#0000ff', 0.2) diagram.line([(graph_x, text_y), (graph_x + width, text_y)], '#0000ff', 0.2) diagram.text( text_x, text_y, '%5s %s %-4d cents' % (describe(w1), ' ' if cents == 0 else ' flat' if cents > 0 else 'sharp', abs(cents))) #_, emission = patched_instrument.resonance_score(w2,fingers,True) #diagram.text(emit_x, text_y, # ', '.join('%.2f' % item for item in emission) # ) phase = patched_instrument.resonance_phase(w2, fingers) diagram.text(emit_x, text_y, "%f" % phase) #if any_extra: #w3 = mod_instrument.true_wavelength_near(w1, fingers) #cents3 = int(round( log2(w3/w1) * 1200.0 )) #diagram.text(graph_x + width, text_y, # '%s %-4d cents grad=%.1f diff=%d' % (' ' if cents3 == 0 else ' flat' if cents3 > 0 else 'sharp', abs(cents3), grad3, cents3-cents) #) text_y -= 25 diagram.text(graph_x, text_y - 10, 'Nearby resonances:', color='#000000') #diagram.text(emit_x, text_y - 20, # 'Volume of sound emission from\n' # 'instrument end and open holes:', # color='#000000', # ) text_y -= 50.0 + 10.0 * max(len(self.inner_diameters), len(self.outer_diameters)) diagram.text(graph_x - 150.0, text_y, 'Outer diameters:', color='#000000') kinks = [0.0] + self.instrument.outer_kinks + [self.instrument.length] for i, item in enumerate(self.outer_diameters): diagram.text( graph_x - 150.0, text_y + 10.0 + (len(self.outer_diameters) - i) * 10.0, describe_low_high(item) + 'mm at %.1fmm' % kinks[i]) diagram.text(graph_x, text_y, 'Inner diameters:', color='#000000') kinks = [0.0] + self.instrument.inner_kinks + [self.instrument.length] for i, item in enumerate(self.inner_diameters): diagram.text( graph_x, text_y + 10.0 + (len(self.inner_diameters) - i) * 10.0, describe_low_high(item) + 'mm at %.1fmm' % kinks[i]) diagram.save(os.path.join(self.output_dir, 'diagram.svg')) del self.instrument
def draw_logarithmic_plot(width, height, title, data, maxpower, filename): """ Create a logarithmic plot as an SVG file from the data and other values supplied as arguments. Save SVG file to specified filename. """ topmargin = 64 bottommargin = 32 leftmargin = 86 rightmargin = 32 graph_height = height - topmargin - bottommargin graph_width = width - leftmargin - rightmargin pixels_per_unit_x = graph_width / (len(data) - 1) pixels_per_unit_y = graph_height / maxpower s = svg.SVG() s.create(width, height) s.fill("#FFFFFF") # header text and border lines s.text(width / 2, 38, "sans-serif", 16, "#000000", "#000000", "middle", title) s.line("#808080", 2, leftmargin, topmargin, leftmargin, height - bottommargin) s.line("#808080", 2, leftmargin, height - bottommargin, width - rightmargin, height - bottommargin) # y axis indexes and values y = height - bottommargin for power in range(0, maxpower + 1): s.line("#808080", 1, leftmargin - 8, y, leftmargin, y) s.text(leftmargin - 12, y + 4, "sans-serif", 10, "#000000", "#000000", "end", str(10**power)) y -= pixels_per_unit_y # x axis indexes and values x = leftmargin for item in data: s.line("#808080", 1, x, height - bottommargin, x, height - bottommargin + 8) s.text(x, height - bottommargin + 24, "sans-serif", 10, "#000000", "#000000", "middle", str(item["label"])) y = height - bottommargin - (math.log10(item["data"]) * pixels_per_unit_y) s.circle("#0000FF", 0, "#0000FF", 3, x, y) x += pixels_per_unit_x # finish off s.finalize() s.save(filename) print("File saved")