Repository: ManimCommunity/manim

Issue:
Remove 'MovingCameraScene.camera_frame' and 'MovingCameraScene.setup'
## Enhancement proposal

[`MovingCameraScene.setup` method](https://github.com/ManimCommunity/manim/blob/2faa89e3d367c370fd101893f03efab63109ceb0/manim/scene/moving_camera_scene.py#L94-L104) only sets the attribute `camera_frame` into the `Scene` instance, pointing to `renderer.camera.frame`, but since the property [`camera` exists in `Scene` class](https://github.com/ManimCommunity/manim/blob/57f228b8eb96f9c99517a7fdb8756b0c4969d7ff/manim/scene/scene.py#L101-L103), the object `renderer.camera.frame` can be accesed using `camera.frame`.

Changing `camera_frame` by `camera.frame` and removing the useless `setup` method, the example `FollowingGraphCamera` could be rewritten as:

```python
class FollowingGraphCamera(GraphScene, MovingCameraScene):
    def setup(self):
        GraphScene.setup(self)

    def construct(self):
        self.camera.frame.save_state()
        self.setup_axes(animate=False)
        graph = self.get_graph(lambda x: np.sin(x),
                               color=BLUE,
                               x_min=0,
                               x_max=3 * PI
                               )
        moving_dot = Dot().move_to(graph.points[0]).set_color(ORANGE)

        dot_at_start_graph = Dot().move_to(graph.points[0])
        dot_at_end_graph = Dot().move_to(graph.points[-1])
        self.add(graph, dot_at_end_graph, dot_at_start_graph, moving_dot)
        self.play(self.camera.frame.animate.scale(0.5).move_to(moving_dot))

        def update_curve(mob):
            mob.move_to(moving_dot.get_center())

        self.camera.frame.add_updater(update_curve)
        self.play(MoveAlongPath(moving_dot, graph, rate_func=linear))
        self.camera.frame.remove_updater(update_curve)

        self.play(Restore(self.camera.frame))
```

Studying the original example, I was confused as to why accessing `camera.frame` was done using` camera_frame`.

### Additional comments

The `setup` method [made sense in the original implementation](https://github.com/ManimCommunity/manim/blame/2981fa2b32f0b3827317efc75df56c0585c6c0f0/scene/moving_camera_scene.py#L11-L17) but with the changes that have happened since then it's just dead code now.


Discussion:

Resolving patch:
diff --git a/manim/scene/moving_camera_scene.py b/manim/scene/moving_camera_scene.py
--- a/manim/scene/moving_camera_scene.py
+++ b/manim/scene/moving_camera_scene.py
@@ -14,10 +14,10 @@ class ChangingCameraWidthAndRestore(MovingCameraScene):
         def construct(self):
             text = Text("Hello World").set_color(BLUE)
             self.add(text)
-            self.camera_frame.save_state()
-            self.play(self.camera_frame.animate.set(width=text.width * 1.2))
+            self.camera.frame.save_state()
+            self.play(self.camera.frame.animate.set(width=text.width * 1.2))
             self.wait(0.3)
-            self.play(Restore(self.camera_frame))
+            self.play(Restore(self.camera.frame))
 
 
 .. manim:: MovingCameraCenter
@@ -28,9 +28,9 @@ def construct(self):
             t = Triangle(color=GREEN, fill_opacity=0.5).move_to(2 * RIGHT)
             self.wait(0.3)
             self.add(s, t)
-            self.play(self.camera_frame.animate.move_to(s))
+            self.play(self.camera.frame.animate.move_to(s))
             self.wait(0.3)
-            self.play(self.camera_frame.animate.move_to(t))
+            self.play(self.camera.frame.animate.move_to(t))
 
 
 .. manim:: MovingAndZoomingCamera
@@ -40,20 +40,20 @@ def construct(self):
             s = Square(color=BLUE, fill_opacity=0.5).move_to(2 * LEFT)
             t = Triangle(color=YELLOW, fill_opacity=0.5).move_to(2 * RIGHT)
             self.add(s, t)
-            self.play(self.camera_frame.animate.move_to(s).set(width=s.width*2))
+            self.play(self.camera.frame.animate.move_to(s).set(width=s.width*2))
             self.wait(0.3)
-            self.play(self.camera_frame.animate.move_to(t).set(width=t.width*2))
+            self.play(self.camera.frame.animate.move_to(t).set(width=t.width*2))
 
-            self.play(self.camera_frame.animate.move_to(ORIGIN).set(width=14))
+            self.play(self.camera.frame.animate.move_to(ORIGIN).set(width=14))
 
 .. manim:: MovingCameraOnGraph
 
     class MovingCameraOnGraph(GraphScene, MovingCameraScene):
         def setup(self):
             GraphScene.setup(self)
-            MovingCameraScene.setup(self)
+
         def construct(self):
-            self.camera_frame.save_state()
+            self.camera.frame.save_state()
             self.setup_axes(animate=False)
             graph = self.get_graph(lambda x: np.sin(x),
                                    color=WHITE,
@@ -63,9 +63,9 @@ def construct(self):
             dot_at_start_graph = Dot().move_to(graph.points[0])
             dot_at_end_graph = Dot().move_to(graph.points[-1])
             self.add(graph, dot_at_end_graph, dot_at_start_graph)
-            self.play(self.camera_frame.animate.scale(0.5).move_to(dot_at_start_graph))
-            self.play(self.camera_frame.animate.move_to(dot_at_end_graph))
-            self.play(Restore(self.camera_frame))
+            self.play(self.camera.frame.animate.scale(0.5).move_to(dot_at_start_graph))
+            self.play(self.camera.frame.animate.move_to(dot_at_end_graph))
+            self.play(Restore(self.camera.frame))
             self.wait()
 
 """
@@ -91,18 +91,6 @@ class MovingCameraScene(Scene):
     def __init__(self, camera_class=MovingCamera, **kwargs):
         Scene.__init__(self, camera_class=camera_class, **kwargs)
 
-    def setup(self):
-        """
-        This method is used internally by Manim
-        to set up the scene for proper use.
-        """
-        Scene.setup(self)
-        assert isinstance(self.renderer.camera, MovingCamera)
-        self.camera_frame = self.renderer.camera.frame
-        # Hmm, this currently relies on the fact that MovingCamera
-        # willd default to a full-sized frame.  Is that okay?
-        return self
-
     def get_moving_mobjects(self, *animations):
         """
         This method returns a list of all of the Mobjects in the Scene that


Test patch: