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

Code before:
                        )
                        color_index = min(color_index, 1)
                        mob_color = interpolate_color(
                            new_colors[i - 1], new_colors[i], color_index
                        )
                        mob.set_color(mob_color, family=False)
                        break

        return self


# Specific shapes


class Sphere(ParametricSurface):
    """A mobject representing a three-dimensional sphere.

    Examples
    ---------

    .. manim:: ExampleSphere
        :save_last_frame:

        class ExampleSphere(ThreeDScene):
            def construct(self):
                self.set_camera_orientation(phi=PI / 6, theta=PI / 6)
                sphere1 = Sphere(
                    center=(3, 0, 0),
                    radius=1,
                    resolution=(20, 20),
                    u_min=0.001,
                    u_max=PI - 0.001,
                    v_min=0,
                    v_max=TAU,
                )
                sphere1.set_color(RED)
                self.add(sphere1)
                sphere2 = Sphere(center=(-1, -3, 0), radius=2, resolution=(18, 18))
                sphere2.set_color(GREEN)
                self.add(sphere2)
                sphere3 = Sphere(center=(-1, 2, 0), radius=2, resolution=(16, 16))
                sphere3.set_color(BLUE)
                self.add(sphere3)
    """

    def __init__(
        self,
        center=ORIGIN,
        radius=1,
        resolution=(12, 24),
        u_min=0.001,

Review comment (bug):
**Nitpick (non-blocking)** : You can shorten this by using numpy. 
To get the closest matching value of z_value in `pivots`, you can do something like that `np.abs(pivots - z_value).argmin()`. This will give the index of the closest value. Beware, it can be the value _above_ z_value, so the line before won't directly work. Check [this](https://stackoverflow.com/questions/2566412/find-nearest-value-in-numpy-array) for the general idea. 

But it's a true nitpick; it's just a matter of code esthetic. I'm fine with how it is right now. 

Code after:

            pivot_min = axes.z_range[0]
            pivot_max = axes.z_range[1]
            pivot_frequency = (pivot_max - pivot_min) / (len(new_colors) - 1)
            pivots = np.arange(
                start=pivot_min, stop=pivot_max + pivot_frequency, step=pivot_frequency
            )

        for mob in self.family_members_with_points():
            z_value = axes.point_to_coords(mob.get_midpoint())[2]
            if z_value <= pivots[0]:
                mob.set_color(new_colors[0])
            elif z_value >= pivots[-1]:
                mob.set_color(new_colors[-1])
            else:
                for i, pivot in enumerate(pivots):
                    if pivot > z_value:
                        color_index = (z_value - pivots[i - 1]) / (
                            pivots[i] - pivots[i - 1]
                        )
                        color_index = min(color_index, 1)
                        mob_color = interpolate_color(
                            new_colors[i - 1], new_colors[i], color_index
                        )
                        mob.set_color(mob_color, family=False)
                        break

        return self


# Specific shapes


class Sphere(ParametricSurface):
    """A mobject representing a three-dimensional sphere.

    Examples
    ---------

    .. manim:: ExampleSphere
        :save_last_frame:

        class ExampleSphere(ThreeDScene):
            def construct(self):
                self.set_camera_orientation(phi=PI / 6, theta=PI / 6)
                sphere1 = Sphere(
                    center=(3, 0, 0),
                    radius=1,
                    resolution=(20, 20),
                    u_range=[0.001, PI - 0.001],
                    v_range=[0, TAU]