Spaces:
Running
Running
| import drawsvg as draw | |
| import numpy as np | |
| def draw_line(d,x1,y1,x2,y2,color): | |
| d.append(draw.Lines(x1,y1, | |
| x2,y2, | |
| close=False, | |
| fill="none", | |
| stroke=color, | |
| stroke_width=2)) | |
| def draw_nucleotide(d,x, y, nt, color): | |
| """ Draw one nucleotide in a circle | |
| """ | |
| assert(len(nt)==1) | |
| d.append(draw.Circle(x, y, 8, | |
| fill=color, stroke_width=2, stroke='black')) | |
| deltax = 4.3 if nt=="A" else (4.5 if nt=="U" else 4.7) | |
| d.append(draw.Text(nt, 11, x-deltax, y+4, fill="black", font_weight="bold")) # use 11pt text | |
| def draw_oligo(d,xs, ys, nts, colors): | |
| lastx = None | |
| lasty = None | |
| for (x,y,nt,color) in zip(xs,ys,nts,colors): # first draw all the black lines connecting the nucleotides | |
| if lastx != None: | |
| draw_line(d,lastx,lasty,x,y,"black") | |
| lastx, lasty = x,y | |
| for (x,y,nt,color) in zip(xs,ys,nts,colors): | |
| draw_nucleotide(d,x,y,nt,color) | |
| BASE_PAIR_COLOR = "#ff4e4e" | |
| DELTA_X = 20 | |
| DELTA_Y = 20 | |
| LOOP_RADIUS_PER_LOOP_LENGTH = {3:18, 4:20, 5:23,6:26} | |
| def draw_stem_loop(nts, stem_length, colors, filename): | |
| """ First nucleotide is just upstream of stem; then stem; then loop; then 3' part of stem; then another nucleotide outside stem | |
| """ | |
| assert(len(nts)==len(colors)) | |
| d = draw.Drawing(500, 200, origin='center') | |
| for i in range(stem_length): | |
| draw_line(d,i*DELTA_X,0,i*DELTA_X,DELTA_Y,BASE_PAIR_COLOR) | |
| loop_length = len(nts) - 2*stem_length - 2 | |
| assert((loop_length >= 3) and (loop_length <= 6)) | |
| loop_radius = LOOP_RADIUS_PER_LOOP_LENGTH[loop_length] | |
| xs = [-0.7*DELTA_X,] + [DELTA_X * i for i in range(stem_length)] + [DELTA_X * (stem_length-1) + loop_radius* np.cos(2*np.pi*(1/2)/(loop_length+2)) - loop_radius * np.cos(2*np.pi*(i+3/2)/(loop_length+2)) for i in range(loop_length)] + [DELTA_X * (stem_length-1-i) for i in range(stem_length)] + [-0.7*DELTA_X] | |
| ys = [-0.7*DELTA_Y,] + [0] * stem_length + [DELTA_Y/2 - loop_radius * np.sin(2*np.pi*(i+3/2)/(loop_length+2)) for i in range(loop_length)] + [DELTA_Y]*stem_length + [1.7*DELTA_Y] | |
| draw_oligo(d,xs,ys,nts,colors) | |
| d.set_pixel_scale(2) # Set number of pixels per geometry unit | |
| d.save_svg(filename) | |