def construct(self): expr2 = self.expr.subs(e, math.e) f = lambdify(x, expr2, 'numpy') domains = continuous_domain(self.expr, x, Interval(self.x_min, self.x_max)) if type(domains) is Union: domains = domains.args else: domains = [domains] self.setup_axes(animate=True) func_graph = VGroup() for domain in domains: graph = self.get_graph(f, self.function_color, get_left_bound(domain), get_right_bound(domain)) func_graph.add(graph) graph_lab = self.get_graph_label(func_graph[0], label=latex(self.expr)) self.play(ShowCreation(func_graph, run_time=3)) self.play(ShowCreation(graph_lab)) self.wait(5)
def __init__(self, diagram: SequenceDiagram, title: str): super().__init__() self.diagram = diagram self.title = title tblock = VGroup() title = Text(title, font=self.CONFIG["text_font"], color=self.CONFIG["actor_text_color"]) rect = (Rectangle(height=self._get_text_height(title) + 0.5, width=title.get_width() + 0.5).round_corners(0.2).set_fill( self.CONFIG["actor_fill_color"], 1)) title.move_to(rect) tblock.add(rect, title) self.block = tblock self.line = DashedLine( start=rect.get_edge_center(DOWN), end=[rect.get_center()[0], rect.get_bottom()[1], 0], stroke_style="dashed", dash_length=DEFAULT_DASH_LENGTH * 4, stroke_width=DEFAULT_STROKE_WIDTH / 2, positive_space_ratio=0.7, ) self.bblock = tblock.copy() self.bblock.next_to(self.line, direction=DOWN, buff=0) self.add(tblock, self.line, self.bblock)
def test_vgroup_init(using_opengl_renderer): """Test the VGroup instantiation.""" VGroup() VGroup(OpenGLVMobject()) VGroup(OpenGLVMobject(), OpenGLVMobject()) with pytest.raises(TypeError): VGroup(OpenGLMobject()) with pytest.raises(TypeError): VGroup(OpenGLMobject(), OpenGLMobject())
def test_vgroup_init(): """Test the VGroup instantiation.""" VGroup() VGroup(VMobject()) VGroup(VMobject(), VMobject()) with pytest.raises(TypeError): VGroup(Mobject()) with pytest.raises(TypeError): VGroup(Mobject(), Mobject())
def test_vgroup_item_assignment_at_correct_position(using_opengl_renderer): """Test VGroup item-assignment adds to correct position for OpenGLVMObjects""" n_items = 10 vgroup = VGroup() for _i in range(n_items): vgroup.add(OpenGLVMobject()) new_obj = OpenGLVMobject() vgroup[6] = new_obj assert vgroup[6] == new_obj assert len(vgroup) == n_items
def test_vgroup_item_assignment_at_correct_position(): """Test VGroup item-assignment adds to correct position for VMObjects""" n_items = 10 vgroup = VGroup() for _i in range(n_items): vgroup.add(VMobject()) new_obj = VMobject() vgroup[6] = new_obj assert vgroup[6] == new_obj assert len(vgroup) == n_items
def construct(self): data = [20, 0, 0, -5] x = [0, 8, 38, 39] self.setup_axes() dot_collection = VGroup() for time, val in enumerate(data): dot = Dot().move_to(self.coords_to_point(x[time], val)) self.add(dot) dot_collection.add(dot) l1 = Line(dot_collection[0].get_center(), dot_collection[1].get_center()) l2 = Line(dot_collection[1].get_center(), dot_collection[2].get_center()) l3 = Line(dot_collection[2].get_center(), dot_collection[3].get_center()) self.add(l1, l2, l3)
def test_vgroup_remove(): """Test the VGroup remove method.""" a = VMobject() c = VMobject() b = VGroup(c) obj = VGroup(a, b) assert len(obj.submobjects) == 2 assert len(b.submobjects) == 1 obj.remove(a) b.remove(c) assert len(obj.submobjects) == 1 assert len(b.submobjects) == 0 obj.remove(b) assert len(obj.submobjects) == 0
def bordered_group( self, *children: Mobject, border_attrs: Optional[Dict] = None, title: Optional[str] = None, title_attrs: Optional[Dict] = None, ): group = VGroup(*children) width = ( abs(max(child.get_x(RIGHT) for child in children) - min(child.get_x(LEFT) for child in children)) + 1.2 ) height = abs(max(child.get_y(UP) for child in children) - min(child.get_y(DOWN) for child in children)) + 1.2 rect = Rectangle(**_merge(border_attrs, width=width, height=height)) rect.move_to(group.get_center_of_mass()) group.add_to_back(rect) if title: label = self.text_box( title, **_merge(title_attrs, bg_color=BLACK, border_color=BLACK, rounded=False, shadow=False) ) label.scale(0.8) label.move_to(group.get_top()) group.add(label) return group
def test_vgroup_remove(using_opengl_renderer): """Test the VGroup remove method.""" a = OpenGLVMobject() c = OpenGLVMobject() b = VGroup(c) obj = VGroup(a, b) assert len(obj.submobjects) == 2 assert len(b.submobjects) == 1 obj.remove(a) b.remove(c) assert len(obj.submobjects) == 1 assert len(b.submobjects) == 0 obj.remove(b) assert len(obj.submobjects) == 0
def test_vgroup_add(): """Test the VGroup add method.""" obj = VGroup() assert len(obj.submobjects) == 0 obj.add(VMobject()) assert len(obj.submobjects) == 1 with pytest.raises(TypeError): obj.add(Mobject()) assert len(obj.submobjects) == 1 with pytest.raises(TypeError): # If only one of the added object is not an instance of VMobject, none of them should be added obj.add(VMobject(), Mobject()) assert len(obj.submobjects) == 1 with pytest.raises(ValueError): # a Mobject cannot contain itself obj.add(obj)
def test_vgroup_add(using_opengl_renderer): """Test the VGroup add method.""" obj = VGroup() assert len(obj.submobjects) == 0 obj.add(OpenGLVMobject()) assert len(obj.submobjects) == 1 with pytest.raises(TypeError): obj.add(OpenGLMobject()) assert len(obj.submobjects) == 1 with pytest.raises(TypeError): # If only one of the added object is not an instance of OpenGLVMobject, none of them should be added obj.add(OpenGLVMobject(), OpenGLMobject()) assert len(obj.submobjects) == 1 with pytest.raises(ValueError): # a OpenGLMobject cannot contain itself obj.add(obj)
def test_vgroup_remove_dunder(): """Test the VGroup __sub__ magic method.""" a = VMobject() c = VMobject() b = VGroup(c) obj = VGroup(a, b) assert len(obj.submobjects) == 2 assert len(b.submobjects) == 1 assert len(obj - a) == 1 assert len(obj.submobjects) == 2 obj -= a b -= c assert len(obj.submobjects) == 1 assert len(b.submobjects) == 0 obj -= b assert len(obj.submobjects) == 0
def test_vgroup_supports_item_assigment(): """Test VGroup supports array-like assignment for VMObjects""" a = VMobject() b = VMobject() vgroup = VGroup(a) assert vgroup[0] == a vgroup[0] = b assert vgroup[0] == b assert len(vgroup) == 1
def test_vgroup_supports_item_assigment(using_opengl_renderer): """Test VGroup supports array-like assignment for OpenGLVMObjects""" a = OpenGLVMobject() b = OpenGLVMobject() vgroup = VGroup(a) assert vgroup[0] == a vgroup[0] = b assert vgroup[0] == b assert len(vgroup) == 1
def __init__(self, icon=SVGS.ANTIBODY, name='Antibody binding\nprediction', **kwargs): super().__init__(**kwargs) self.icon = icon self.name = name if not isinstance(self.icon, Mobject): self.icon = SVGMobject( self.icon).set_color_by_gradient(BLUE).scale(0.6) if not isinstance(self.name, Mobject): self.name = (VGroup( *(Text(name) for name in self.name.splitlines())).scale(0.5).arrange( DOWN, center=True, buff=SMALL_BUFF)) self.name.next_to(self.icon, DOWN) self.icon_name = VGroup(self.icon, self.name) self.frame = SurroundingRectangle( self.icon_name).round_corners(0.5).set_color(WHITE) self.add(self.frame, self.icon_name)
def hiv_antibody(): """Returns mobjects for the hiv antibody sequence""" # Amino acid level - heavy and HCDR3 of the HIV antibody # Likely this is too complex for the purpose in this video heavy = [ aa_text(line) for line in HIV_ANTIBODY_HEAVY.splitlines(keepends=False)[:-1] # N.B. for aesthetics, remove the last line ] heavy = VGroup(*heavy).scale(0.4).arrange(DOWN, center=False) hcdr3 = aa_text(HIB_ANTIBODY_HCDR3).scale(0.4) return heavy, hcdr3
def __init__(self, source: Actor, label: str): super().__init__(source) self.label = "\n".join(wrap(label, 30)) line_block = VGroup() spacing = 0.4 distance = 0.8 center_x = source.get_center()[0] line = Polygon( [center_x, spacing, 0], [center_x + distance, spacing, 0], [center_x + distance, -1 * spacing, 0], [center_x + distance / 2, -1 * spacing, 0], [center_x + distance, -1 * spacing, 0], [center_x + distance, spacing, 0], [center_x, spacing, 0], color=WHITE, ) line.set_stroke(width=ARROW_STROKE_WIDTH) arrow = Arrow( start=[center_x + distance, -1 * spacing, 0], end=[center_x, -1 * spacing, 0], buff=0, stroke_width=ARROW_STROKE_WIDTH, ) line_block.add(line, arrow) title = Text(self.label, font=self.source.font, size=0.5, slant=ITALIC) title.next_to(line_block) block = VGroup() block.add(line_block, title) block.next_to(source.get_center(), RIGHT) self.add(block)
def construct(self): rng = np.random.RandomState(self.seed) moleculizer = partial( new_molecule, colors=lambda: rng.choice(MOLECULE_COLORS, size=3, replace=True)) proteins = molecule_universe_grid( moleculizer, num_molecules=(5, 8)).scale(0.3).center() proteins_frame = SurroundingRectangle(proteins, color=WHITE).round_corners(0.5) universe_title = Text('Known proteins').scale(0.7).next_to( proteins_frame, UP) framed_proteins = VGroup(universe_title, proteins_frame, proteins).to_edge(LEFT) self.play(FadeIn(framed_proteins)) self.wait(3) # --- Sequence -> Number -> MLM heavy, hcdr3 = hiv_antibody() heavy.next_to(framed_proteins, RIGHT) self.play(Transform(proteins[23], heavy)) self.wait(5) mlm = MLM().next_to(framed_proteins, RIGHT) self.play(ShrinkToCenter(heavy)) # , mlm.text self.wait(5) # FIXME: just to break here if mlm.text is not None: return # --- Subsets selected_proteins = [ proteins[i].copy() for i in rng.choice( len(proteins), replace=False, size=len(proteins) // 3) ] antibodies = VGroup( * [molecule_from_molecule(protein) for protein in selected_proteins]) antibodies_frame = (SurroundingRectangle(antibodies).match_color( proteins_frame).match_width(proteins_frame).match_height( proteins_frame)).round_corners(0.5) framed_antibodies = VGroup(antibodies_frame, antibodies) framed_antibodies.next_to(proteins, RIGHT, buff=MED_LARGE_BUFF) self.play( *[ ReplacementTransform(protein, antibody) for protein, antibody in zip(selected_proteins, antibodies) ], Write(antibodies_frame)) self.wait(4)
def _box( self, parent: VGroup, bg_color, color, rounded, shadow, text, wrap_at, border_color, text_attrs: Optional[dict], border_builder: Callable[[Text], Polygon], ) -> VGroup: if wrap_at: text = "\n".join(wrap(text, wrap_at)) title = Text(text, font=self.text_font, color=color, **(text_attrs if text_attrs else {})) border = border_builder(title) border.set_color(border_color) bg_color, bg_opacity = self._color_and_opacity(bg_color, text) border.set_fill(color=bg_color, opacity=bg_opacity) if rounded: border.round_corners(ROUNDED_RADIUS) title.move_to(border) parent.add(border, title) if shadow and bg_opacity: s_rect = border.copy() s_rect.set_color(SHADOW_COLOR) shadow_opacity = SHADOW_OPACITY s_rect.set_stroke(width=0) s_rect.set_background_stroke(color=GREEN, opacity=shadow_opacity, width=0) s_rect.set_fill(opacity=shadow_opacity) s_rect.scale(1 + SHADOW_SHIFT) s_rect.shift(SHADOW_SHIFT * DR) parent.add_to_back(s_rect) return parent
def __init__(self, target: Actor, label: str): super().__init__(target) self.target = target self.label = "\n".join(wrap(label, 30)) line_block = VGroup() spacing = 0.4 distance = 0.8 line = Polygon( [target.get_center()[0], spacing, 0], [target.get_center()[0] + distance, spacing, 0], [target.get_center()[0] + distance, -1 * spacing, 0], [target.get_center()[0] + distance / 2, -1 * spacing, 0], [target.get_center()[0] + distance, -1 * spacing, 0], [target.get_center()[0] + distance, spacing, 0], [target.get_center()[0], spacing, 0], color=WHITE, ) line.set_stroke(width=ARROW_STROKE_WIDTH) arrow = Arrow( start=[target.get_center()[0] + distance, -1 * spacing, 0], end=[target.get_center()[0], -1 * spacing, 0], buff=0, stroke_width=ARROW_STROKE_WIDTH, ) line_block.add(line, arrow) title = Text(self.label, font="Helvetica", size=0.7, slant=ITALIC) title.next_to(line_block) block = VGroup() block.add(line_block, title) block.next_to(target.get_center(), RIGHT) self.add(block)
def test_vgroup_add_dunder(): """Test the VGroup __add__ magic method.""" obj = VGroup() assert len(obj.submobjects) == 0 obj + VMobject() assert len(obj.submobjects) == 0 obj += VMobject() assert len(obj.submobjects) == 1 with pytest.raises(TypeError): obj += Mobject() assert len(obj.submobjects) == 1 with pytest.raises(TypeError): # If only one of the added object is not an instance of VMobject, none of them should be added obj += (VMobject(), Mobject()) assert len(obj.submobjects) == 1 with pytest.raises(Exception): # TODO change this to ValueError once #307 is merged # a Mobject cannot contain itself obj += obj
def __init__(self, target: Actor, label: str, direction: np.array): super().__init__(target) self.target = target self.label = "\n".join(wrap(label, 30)) self.direction = direction block = VGroup() title = Text(self.label, font="Helvetica").scale(0.7) rect = Rectangle(height=title.get_height() + 0.3, width=title.get_width() + 0.3) title.move_to(rect) block.add(rect, title) block.next_to(target.get_center(), direction) self.add(block)
def molecule_universe_grid(moleculer=new_molecule, num_molecules: Union[int, Tuple[int, int]] = 5): try: num_rows, num_cols = num_molecules except TypeError: num_rows = num_cols = num_molecules proteins = [] prev_row = None for _ in range(num_rows): protein = moleculer() if prev_row is not None: protein.next_to(prev_row, RIGHT, buff=SMALL_BUFF) prev_row = protein proteins.append(protein) prev_col = protein for _ in range(num_cols): protein = moleculer() protein.next_to(prev_col, DOWN, buff=SMALL_BUFF) prev_col = protein proteins.append(protein) return VGroup(*proteins)
def construct(self): a_million_forks = Text('A million forks in the road to our products' ) # to drug development a_million_forks.to_edge(UP) new_drugs_per_billion_RD = [('1950', 100), ('1960', 50), ('1970', 10), ('1980', 5), ('1990', 3), ('2000', 2), ('2010', 1), ('2020', 1)] x = [x for x, _ in new_drugs_per_billion_RD] y = [y for _, y in new_drugs_per_billion_RD] colors = ["#003f5c", "#58508d", "#bc5090", "#ff6361", "#ffa600"] chart = BarChart( values=y, max_value=max(y), bar_colors=colors, bar_names=x, bar_label_scale_val=0.5, ).scale(0.8).to_edge(LEFT).shift(0.5 * DOWN) # text_top = ( # Text('EROOM\'s Law: More expensive, slower drug discovery') # .scale(0.9) # .next_to(chart, UP, buff=0.1) # ) # text_left = ( # Text('Number of drugs per billion US$ R&D spending') # .rotate(angle=TAU / 4, axis=OUT) # .scale(0.3) # .next_to(chart, LEFT, buff=0.5) # ) text_top = ( Text('Number of drugs per billion US$ R&D spending (log-scale)' ).scale(0.3).next_to(chart, UP, buff=0.5)) text_bottom = ( Text("Eroom's law: a continuous decline in Pharma R&D productivity" ).scale(0.3).next_to(chart, DOWN, buff=0.5)) # --- Examples of forks in the road icons_text = [ (SVGMobject(SVGS.ANTIBODY).set_color(BLUE).scale(0.8), Text('Is my antibody a potent, functional binder?')), (SVGMobject(SVGS.CYCLIC_PEPTIDE).set_color_by_gradient( BLUE, GREEN).scale(0.8), Text('Can we generate peptides without liabilities?')), (SVGMobject(SVGS.DNA).set_color_by_gradient(GREEN, BLUE).scale(0.8), Text( 'Can we optimize DNA to better express traits in plants or humans?' )), (SVGMobject(SVGS.PACMAN).set_color(RED).scale(0.8), Text('What will an enzyme in the human gut do?')), # ( # SVGMobject(SVGS.PACMAN).set_color_by_gradient(GREEN, BLUE, RED).scale(0.8), # Text('Can we optimize enzymes to better manufacture bioproducts?') # ), (SVGMobject(SVGS.PROTEIN3D).set_color_by_gradient( GREEN, BLUE, RED).scale(0.8), Text('What is the 3D structure of my biomolecule?')), (SVGMobject(SVGS.PATIENT).set_color_by_gradient(BLUE, RED).scale(0.8), Text('Will a patient respond to treatment in a clinical trial?')), (SVGMobject(SVGS.MUTATION).set_color_by_gradient(BLUE, GREEN, RED).scale(0.8), Text('...')) ] # icons_text = icons_text[:1] for (icon1, _), (icon2, _) in zip(icons_text, icons_text[1:]): icon2.next_to(icon1, DOWN, buff=0.5) for icon, text in icons_text: text.next_to(icon, RIGHT) questions = VGroup(*chain.from_iterable(icons_text)) questions.scale(0.32) questions.next_to(chart, RIGHT, buff=1).shift(0.5 * UP) logo = LoLLogo().scale(0.7) # logo.next_to(questions, DOWN, buff=0.5) logo.move_to(questions) # --- Animate self.play(FadeIn(text_top)) self.play(Write(chart), Write(text_bottom), run_time=4) self.wait(2) self.play(Write(a_million_forks)) for icon, text in icons_text: self.play(FadeIn(icon, text)) self.wait(3) # if we have put the logo under the questions... # self.play(FadeIn(logo)) # if we prefer the logo to morph from the questions actionable_insights = (Text( 'Getting actionable insights from biological sequences').next_to( logo, DOWN, buff=0.5).scale(0.4)) self.play(ReplacementTransform(questions, logo)) self.play(Write(actionable_insights)) self.wait(2)
def test_vmobject_different_num_points_and_submobjects_become(): a = Square() b = VGroup(Circle(), Square()) a.become(b) np.testing.assert_array_equal(a.points, b.points) assert len(a.submobjects) == len(b.submobjects)
def test_vgroup_item_assignment_only_allows_vmobjects(): """Test VGroup item-assignment raises TypeError when invalid type is passed""" vgroup = VGroup(VMobject()) with pytest.raises(TypeError, match="All submobjects must be of type VMobject"): vgroup[0] = "invalid object"
def code_line(*args, language=None): out = VGroup(*[DraculaCode(text=text, language=language) for text in args]) out.arrange(direction=RIGHT) return out
def code_group(*args, language=None): out = VGroup(*[code_line(*text, language=language) for text in args]) out.arrange(direction=DOWN, center=False) for elm in out: elm.align_to(out.get_left(), direction=LEFT) return out
def construct(self): super().construct() # Group first row and second row use_cases = [] for use_case1, use_case2 in zip(USE_CASES, USE_CASES[5:]): use_case2.next_to(use_case1, DOWN, buff=0.5) use_cases.append(VGroup(use_case1, use_case2)) use_cases = VGroup(*use_cases) # Make all use cases same width and height widest = sorted(use_cases, key=lambda x: x.width)[-1] tallest = sorted(chain.from_iterable(use_cases), key=lambda x: x.height)[-1] for use_case_top, use_case_bottom in use_cases: use_case_top.frame.stretch_to_fit_width(widest.width) use_case_top.frame.stretch_to_fit_height(tallest.height) use_case_bottom.frame.stretch_to_fit_width(widest.width) use_case_bottom.frame.stretch_to_fit_height(tallest.height) use_cases.arrange().scale(0.8).center() # Human friendly names for use cases antibodies = use_cases[0][0] peptides_ppi = use_cases[0][1] toxins = use_cases[1][0] peptides_sol = use_cases[1][1] enzyme_stabilisation = use_cases[2][0] microbiome = use_cases[2][1] codons = use_cases[3][0] detoxification = use_cases[3][1] clinical = use_cases[4][0] mutation = use_cases[4][1] # --- Animate! # Create the use cases self.play(Write(use_cases)) self.wait(1) # Example setting the camera old_width = self.camera.frame_width if self.zoom_each_use_case: for use_case in chain.from_iterable(use_cases): self.play( self.camera.frame.animate.move_to(use_case).set( width=use_case.width * 2)) self.wait(2) self.play( self.camera.frame.animate.move_to(ORIGIN).set(width=old_width)) self.wait(2) # Highlight groups with common / synergies # Indications to apply to group visually, temporarily, use cases # https://docs.manim.community/en/stable/reference/manim.animation.indication.html # Similar modalities (some of these are a bit of a stretch to group together) if self.all_groups_at_same_time: self.play( FocusOn(antibodies), # Peptides Wiggle(peptides_sol), Wiggle(peptides_ppi), # DNA + RNA Indicate(codons), Indicate(mutation), Indicate(clinical), # Proteins Circumscribe(toxins.frame), Circumscribe(detoxification.frame), # Enzyme ApplyWave(enzyme_stabilisation), ApplyWave(microbiome), run_time=3) self.wait(6)