Repository: ManimCommunity/manim
File: manim/mobject/three_dimensions.py (Python)

Code before:
from ..mobject.types.vectorized_mobject import VGroup, VMobject
from ..utils.color import *
from ..utils.iterables import tuplify
from ..utils.space_ops import normalize, z_to_vector


class ThreeDVMobject(VMobject):
    def __init__(self, shade_in_3d=True, **kwargs):
        super().__init__(shade_in_3d=shade_in_3d, **kwargs)


class ParametricSurface(VGroup):
    """Creates a Parametric Surface

    Exanples
    --------
    .. manim:: ParaSurface
        :save_last_frame:

        class ParaSurface(ThreeDScene):
            def func(self, u, v):
                return np.array([np.cos(u) * np.cos(v), np.cos(u) * np.sin(v), u])

            def construct(self):
                axes = ThreeDAxes()
                surface = ParametricSurface(self.func, u_min=-TAU, u_max=TAU / 2, v_min=0, v_max=2 * PI)
                self.set_camera_orientation(theta=70 * DEGREES, phi=75 * DEGREES)
                self.add(axes, surface)
    """

    def __init__(
        self,
        func,
        u_min=0,
        u_max=1,
        v_min=0,
        v_max=1,
        resolution=32,
        surface_piece_config={},
        fill_color=BLUE_D,
        fill_opacity=1.0,
        checkerboard_colors=[BLUE_D, BLUE_E],
        stroke_color=LIGHT_GREY,
        stroke_width=0.5,
        should_make_jagged=False,
        pre_function_handle_to_anchor_scale_factor=0.00001,
        **kwargs
    ):
        VGroup.__init__(self, **kwargs)
        self.u_min = u_min
        self.u_max = u_max

Review comment (suggestion):
This will produce the correct representation of the intended surface only when the `unit_size`s of all the individual axes are exactly equal to 1, which is not the case here. Whenever a graph or a surface is "tied" to `Axes` / `ThreeDAxes`, the corresponding `c2p` function has to be used to ensure that the coordinates are scaled and/or shifted appropriately.

Also, I don't really like that the current surface doesn't quite fit in the frame. So I'd suggest decreasing the u-range.
```suggestion
                surface = ParametricSurface(
                    lambda u, v: axes.c2p(*self.func(u, v)),
                    u_min=-PI,
                    u_max=PI,
                    v_min=0,
                    v_max=TAU,
                )
```

Code after:
from ..mobject.types.vectorized_mobject import VGroup, VMobject
from ..utils.color import *
from ..utils.iterables import tuplify
from ..utils.space_ops import normalize, z_to_vector


class ThreeDVMobject(VMobject):
    def __init__(self, shade_in_3d=True, **kwargs):
        super().__init__(shade_in_3d=shade_in_3d, **kwargs)


class ParametricSurface(VGroup):
    """Creates a Parametric Surface

    Examples
    --------
    .. manim:: ParaSurface
        :save_last_frame:

        class ParaSurface(ThreeDScene):
            def func(self, u, v):
                return np.array([np.cos(u) * np.cos(v), np.cos(u) * np.sin(v), u])

            def construct(self):
                axes = ThreeDAxes(x_range=[-4,4], x_length=8)
                surface = ParametricSurface(
                    lambda u, v: axes.c2p(*self.func(u, v)),
                    u_min=-PI,
                    u_max=PI,
                    v_min=0,
                    v_max=TAU,
                )
                self.set_camera_orientation(theta=70 * DEGREES, phi=75 * DEGREES)
                self.add(axes, surface)
    """

    def __init__(
        self,
        func,
        u_min=0,
        u_max=1,
        v_min=0,
        v_max=1,
        resolution=32,
        surface_piece_config={},
        fill_color=BLUE_D,
        fill_opacity=1.0,
        checkerboard_colors=[BLUE_D, BLUE_E],
        stroke_color=LIGHT_GREY,
        stroke_width=0.5,
        should_make_jagged=False,