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

Code before:
        )

        self.z_normal = z_normal
        self.num_axis_pieces = num_axis_pieces

        self.light_source = light_source

        self.dimension = 3

        if self.z_axis_config.get("scaling") is None or isinstance(
            self.z_axis_config.get("scaling"), LinearBase
        ):
            self.z_axis_config["exclude_origin_tick"] = True
        else:
            self.z_axis_config["exclude_origin_tick"] = False

        z_axis = self._create_axis(self.z_range, self.z_axis_config, self.z_length)

        z_axis.rotate_about_zero(-PI / 2, UP)
        z_axis.rotate_about_zero(angle_of_vector(self.z_normal))
        z_axis.shift(
            self.x_axis.number_to_point(
                self._origin_shift([self.x_axis.x_min, self.x_axis.x_max]),
            ),
        )

        self.axes.add(z_axis)
        self.add(z_axis)
        self.z_axis = z_axis

        if config.renderer != "opengl":
            self._add_3d_pieces()
            self._set_axis_shading()

    def _add_3d_pieces(self):
        for axis in self.axes:
            axis.pieces = VGroup(*axis.get_pieces(self.num_axis_pieces))
            axis.add(axis.pieces)
            axis.set_stroke(width=0, family=False)
            axis.set_shade_in_3d(True)

    def _set_axis_shading(self):
        def make_func(axis):
            vect = self.light_source
            return lambda: (
                axis.get_edge_center(-vect),
                axis.get_edge_center(vect),
            )

        for axis in self:
            for submob in axis.family_members_with_points():

Review comment (suggestion):
There's still a problem if the z_range doesn't include 0, this should help with that.
```suggestion
        z_axis.shift(-z_axis.number_to_point(self._origin_shift(z_axis.x_range)))
        z_axis.shift(
```

Code after:
        )

        self.z_normal = z_normal
        self.num_axis_pieces = num_axis_pieces

        self.light_source = light_source

        self.dimension = 3

        if self.z_axis_config.get("scaling") is None or isinstance(
            self.z_axis_config.get("scaling"), LinearBase
        ):
            self.z_axis_config["exclude_origin_tick"] = True
        else:
            self.z_axis_config["exclude_origin_tick"] = False

        z_axis = self._create_axis(self.z_range, self.z_axis_config, self.z_length)

        # [ax.x_min, ax.x_max] used to account for LogBase() scaling
        # where ax.x_range[0] != ax.x_min
        z_origin = self._origin_shift([z_axis.x_min, z_axis.x_max])

        z_axis.rotate_about_number(z_origin, -PI / 2, UP)
        z_axis.rotate_about_number(z_origin, angle_of_vector(self.z_normal))
        z_axis.shift(-z_axis.number_to_point(z_origin))
        z_axis.shift(
            self.x_axis.number_to_point(
                self._origin_shift([self.x_axis.x_min, self.x_axis.x_max]),
            ),
        )

        self.axes.add(z_axis)
        self.add(z_axis)
        self.z_axis = z_axis

        if config.renderer != "opengl":
            self._add_3d_pieces()
            self._set_axis_shading()

    def _add_3d_pieces(self):
        for axis in self.axes:
            axis.pieces = VGroup(*axis.get_pieces(self.num_axis_pieces))
            axis.add(axis.pieces)
            axis.set_stroke(width=0, family=False)
            axis.set_shade_in_3d(True)

    def _set_axis_shading(self):
        def make_func(axis):
            vect = self.light_source
            return lambda: (
                axis.get_edge_center(-vect),