def test_reverse_arrow(svg_differ): f, expected_svg = start_drawing(200, 55) expected_svg.append(Line(7, 10, 175, 10, stroke='black')) expected_svg.append(Circle(175 / 2, 20, 10, stroke='black', fill='ivory')) expected_svg.append( Text('X', 11, 175 / 2, 20, text_anchor='middle', dy="0.35em")) expected_svg.append(Lines(0, 10, 7, 13.5, 7, 6.5, 0, 10, fill='black')) f.add(Arrow(175, 0, h=20, elevation=-1, label='X')) svg = f.show() svg_differ.assert_equal(svg, expected_svg, 'test_arrow')
def test_arrow(svg_differ): f, expected_svg = start_drawing(200, 55) expected_svg.append(Line(0, 20, 168, 20, stroke='black')) expected_svg.append(Circle(175 / 2, 20, 10, stroke='black', fill='ivory')) expected_svg.append( Text('1.2', 11, 175 / 2, 20, text_anchor='middle', dy="0.35em")) expected_svg.append( Lines(175, 20, 168, 23.5, 168, 16.5, 175, 20, fill='black')) f.add(Arrow(0, 175, h=20, label='1.2')) svg = f.show() svg_differ.assert_equal(svg, expected_svg, 'test_arrow')
def draw_arrow(self, start, end, y, label): r = 10 arrow_size = 7 direction = copysign(1, end - start) centre = (start + end - direction * arrow_size) / 2 centre_start = centre - direction * r centre_end = centre + direction * r self.drawing.append(Line(start, y, centre_start, y, stroke='black')) self.drawing.append(Line(centre_end, y, end, y, stroke='black')) self.drawing.append(Circle(centre, y, r, fill='ivory', stroke='black')) self.drawing.append( Text(label, 15, centre, y, text_anchor='middle', dy="0.3em")) arrow_end = end arrow_start = arrow_end - arrow_size * direction self.drawing.append( Lines(arrow_end, y, arrow_start, y + arrow_size / 2, arrow_start, y - arrow_size / 2, fill='black'))
def test_small_arrow(svg_differ): f, expected_svg = start_drawing(200, 55) expected_svg.append(Line(100, 10, 125, 10, stroke='black')) expected_svg.append(Circle(116, 20, 10, stroke='black', fill='ivory')) expected_svg.append( Text('2.3', 11, 116, 20, text_anchor='middle', dy="0.35em")) expected_svg.append( Lines(132, 10, 125, 13.5, 125, 6.5, 132, 10, fill='black')) f.add(Arrow(100, 132, h=20, elevation=-1, label='2.3')) svg = f.show() svg_differ.assert_equal(svg, expected_svg, 'test_arrow')
def test_scaled_arrow(svg_differ): expected_svg = Drawing(100, 35, origin=(0, 0)) expected_svg.append(Line(0, 10, 93, 10, stroke='black')) expected_svg.append(Circle(50, 20, 10, stroke='black', fill='ivory')) expected_svg.append( Text('2.3', 11, 50, 20, text_anchor='middle', dy="0.35em")) expected_svg.append( Lines(100, 10, 93, 13.5, 93, 6.5, 100, 10, fill='black')) f = Figure() f.add(Arrow(0, 200, h=20, elevation=-1, label='2.3')) svg = f.show(w=100) svg_differ.assert_equal(svg, expected_svg, 'test_arrow')
def draw_schedule(g, model, filename): zeta, chi, duration, label = model TOP = 30 BOTTOM = 30 LEFT = 100 RIGHT = 30 WIDTH = 800 HEIGHT = 800 ROW_OFFSET = 20 TEXT_OFFSET = 40 FONTSIZE = 30 d = Drawing(WIDTH, HEIGHT) d.append(Rectangle(0, 0, WIDTH, HEIGHT, fill='white')) N_tasks = g.num_vertices() N_rounds = len(zeta) - N_tasks min_t = min(zeta[:N_tasks] - g.vertex_properties['durations'].get_array()) max_t = max(zeta) quantum = (WIDTH - RIGHT - LEFT) / (max_t - min_t) block_height = (HEIGHT - TOP - BOTTOM - ROW_OFFSET * (N_tasks)) / (N_tasks + 1) for i in range(N_tasks): color = list(Color('red').range_to('green', 1000))[max( 0, int(g.vertex_properties['soft'][i] * 999))] d.append( Rectangle(quantum * abs(min_t) + LEFT + quantum * (zeta[i] - g.vertex_properties['durations'][i]), HEIGHT - TOP - ROW_OFFSET * i - block_height * (i + 1), quantum * g.vertex_properties['durations'][i], block_height, fill=color.get_hex_l(), stroke_width=2, stroke='black')) if g.vertex_properties['deadlines'][i] >= 0: x = quantum * abs(min_t) + LEFT + quantum * ( g.vertex_properties['deadlines'][i]) d.append( Line(x, HEIGHT - TOP - ROW_OFFSET * i - block_height * (i + 1), x, HEIGHT - TOP - ROW_OFFSET * i - block_height * i, stroke_width=4, stroke='purple')) d.append( Text(str(i), FONTSIZE, TEXT_OFFSET, HEIGHT - TOP - ROW_OFFSET * i - block_height * (i + 1) + block_height / 2, center=True, fill='black')) for i in range(N_rounds): if duration[i] == 0: continue d.append( Rectangle(quantum * abs(min_t) + LEFT + quantum * (zeta[N_tasks + i] - duration[i]), HEIGHT - TOP - ROW_OFFSET * N_tasks - block_height * (N_tasks + 1), quantum * duration[i], block_height, fill='gray', stroke_width=2, stroke='black')) d.append( Text('LWB', FONTSIZE, TEXT_OFFSET, HEIGHT - TOP - ROW_OFFSET * N_tasks - block_height * (N_tasks + 1) + block_height / 2, center=True, fill='black')) d.savePng(filename)
def main(): args = parse_args() source_bins = load_read_bins(args.remap1_csv) target_bins = load_read_bins(args.remap2_csv) all_keys = set(source_bins) all_keys.update(target_bins) moves = defaultdict(Counter) # {source_bin: {target_bin: count}} for read_key in all_keys: source_bin = source_bins.get(read_key) target_bin = target_bins.get(read_key) bin_moves = moves[source_bin] bin_moves[target_bin] += 1 old_unmapped = moves.pop(None, None) sorted_moves = sorted(moves.items()) if old_unmapped: sorted_moves.insert(0, (None, old_unmapped)) diagram_path = args.compare_mapping_svg f = build_coverage_figure(args.genome_coverage1_csv) del f.elements[6:] ref_y, ref = f.elements[5] f2 = build_coverage_figure(args.genome_coverage2_csv) coverage3_y, coverage3 = f2.elements[4] contig3_y, contig3 = f2.elements[5] coverage1_y, coverage1 = f2.elements[6] contig1_y, contig1 = f2.elements[7] dashes_y, dashes = f2.elements[10] del f2.elements[4:] # contig_y, contig = f2.elements[6] # f.h += 50 f.w = max(f.w, f2.w) f.add(coverage3, gap=-4) f.add(contig3, gap=30) contig3_y = f.elements[-1][0] coverage1.a = 0 f.add(coverage1, gap=-4) contig1_shift = contig1.tracks[0].a for track in contig1.tracks: if track.a >= contig1_shift: track.a -= contig1_shift track.b -= contig1_shift f.add(contig1) contig1_y = f.elements[-1][0] if __name__ != '__live_coding__': drawing_width = 970 else: # noinspection PyProtectedMember turtle_screen = Turtle._screen drawing_width = turtle_screen.cv.cget('width') - 10 diagram_path = None drawing = f.show(w=drawing_width) seed1_y = f.h - f.elements[5][0] - 10 seed2_y = f.h - f.elements[7][0] + 25 ref_y = f.h - ref_y contig_y = f.h - contig1_y + 25 contig_x = 0 x_scale = drawing_width / f.w blast_display = BlastDisplay(drawing, x_scale, ref_y, contig_x, contig_y) blast_rows = list(DictReader(args.blast2_csv)) blast_rows.sort(key=lambda match: int(match['score']), reverse=True) best_ref = None matched_positions = set() for row in blast_rows: if '003' not in row['contig_name']: continue if best_ref is None: best_ref = row['ref_name'] elif row['ref_name'] != best_ref: continue start = int(row['start']) end = int(row['end']) new_positions = set(range(start, end)) collisions = matched_positions & new_positions collision_fraction = len(collisions) / len(new_positions) if collision_fraction < 0.1: matched_positions |= new_positions ref_start = int(row['ref_start']) ref_end = int(row['ref_end']) blast_display.add_match(start, end, ref_start, ref_end) blast_display.draw() for source_bin, bin_moves in sorted_moves: total = sum(bin_moves.values()) for i, (target_bin, count) in enumerate(bin_moves.most_common()): fraction = count / total if fraction < 0.1: break if i == 0: print(source_bin, end=':') print(f'\t{target_bin}({fraction})') source_shift = 0 target_shift = contig_x * x_scale if source_bin is None: source_x = target_bin source_y = seed2_y - 10 source_shift = target_shift else: source_x = source_bin source_y = seed1_y if target_bin is None: target_x = source_bin target_y = seed1_y + 10 target_shift = source_shift else: target_x = target_bin target_y = seed2_y source_x *= 100 * x_scale target_x *= 100 * x_scale source_x += source_shift target_x += target_shift drawing.append( Line(source_x, source_y, target_x, target_y, stroke='black', stroke_width=2 * fraction, stroke_opacity=0.25)) if diagram_path is not None: drawing.saveSvg(diagram_path) else: display_image(drawing)