We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
numpy not imported in `manim.mobject.probability`
## Description of bug / unexpected behavior
<!-- Add a clear and concise description of the problem you encountered. -->
When you try to use `BarChart` it raises an error saying `np is not defined`

## Expected behavior
<!-- Add a clear and concise description of what you expected to happen. -->
To not get the error and show the bar chart.

## How to reproduce the issue
<!-- Provide a piece of code illustrating the undesired behavior. -->

<details><summary>Code for reproducing the problem</summary>

```py
class Barchart(Scene):
  def construct(self):
    ls = [12,12,13,15,19,20,21]
    bg = BarChart(ls)
    self.add(bg)
```

</details>


## Additional media files
<!-- Paste in the files manim produced on rendering the code above. -->

<details><summary>Images/GIFs</summary>

<!-- PASTE MEDIA HERE -->

</details>


## Logs
<details><summary>Terminal output</summary>
<!-- Add "-v DEBUG" when calling manim to generate more detailed logs -->

```
<string> in <module>

<string> in construct(self)

/usr/local/lib/python3.7/dist-packages/manim/mobject/probability.py in add_axes(self, width, height)
    197         x_axis = Line(self.tick_width * LEFT / 2, width * RIGHT)
    198         y_axis = Line(MED_LARGE_BUFF * DOWN, height * UP)
--> 199         ticks = VGroup()
    200         heights = np.linspace(0, height, self.n_ticks + 1)
    201         values = np.linspace(0, self.max_value, self.n_ticks + 1)

NameError: name 'np' is not defined
```

<!-- Insert screenshots here (only when absolutely necessary, we prefer copy/pasted output!) -->

</details>


## System specifications

<details><summary>System Details</summary>

- OS (with version, e.g Windows 10 v2004 or macOS 10.15 (Catalina)):
- RAM:
- Python version (`python/py/python3 --version`):
- Installed modules (provide output from `pip list`):
```
Google Colab
```
</details>

<details><summary>LaTeX details</summary>

+ LaTeX distribution (e.g. TeX Live 2020):
+ Installed LaTeX packages:
<!-- output of `tlmgr list --only-installed` for TeX Live or a screenshot of the Packages page for MikTeX -->
</details>

<details><summary>FFMPEG</summary>

Output of `ffmpeg -version`:

```
PASTE HERE
```
</details>

## Additional comments
<!-- Add further context that you think might be relevant for this issue here. -->


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `manim/mobject/probability.py`
Content:
```
1 """Mobjects representing objects from probability theory and statistics."""
2 
3 __all__ = ["SampleSpace", "BarChart"]
4 
5 
6 from ..constants import *
7 from ..mobject.geometry import Line, Rectangle
8 from ..mobject.mobject import Mobject
9 from ..mobject.opengl_mobject import OpenGLMobject
10 from ..mobject.svg.brace import Brace
11 from ..mobject.svg.tex_mobject import MathTex, Tex
12 from ..mobject.types.vectorized_mobject import VGroup
13 from ..utils.color import (
14     BLUE,
15     BLUE_E,
16     DARK_GREY,
17     GREEN_E,
18     LIGHT_GREY,
19     MAROON_B,
20     YELLOW,
21     color_gradient,
22 )
23 from ..utils.iterables import tuplify
24 
25 EPSILON = 0.0001
26 
27 
28 class SampleSpace(Rectangle):
29     def __init__(
30         self,
31         height=3,
32         width=3,
33         fill_color=DARK_GREY,
34         fill_opacity=1,
35         stroke_width=0.5,
36         stroke_color=LIGHT_GREY,
37         default_label_scale_val=1,
38     ):
39         Rectangle.__init__(
40             self,
41             height=height,
42             width=width,
43             fill_color=fill_color,
44             fill_opacity=fill_opacity,
45             stroke_width=stroke_width,
46             stroke_color=stroke_color,
47         )
48         self.default_label_scale_val = default_label_scale_val
49 
50     def add_title(self, title="Sample space", buff=MED_SMALL_BUFF):
51         # TODO, should this really exist in SampleSpaceScene
52         title_mob = Tex(title)
53         if title_mob.width > self.width:
54             title_mob.width = self.width
55         title_mob.next_to(self, UP, buff=buff)
56         self.title = title_mob
57         self.add(title_mob)
58 
59     def add_label(self, label):
60         self.label = label
61 
62     def complete_p_list(self, p_list):
63         new_p_list = list(tuplify(p_list))
64         remainder = 1.0 - sum(new_p_list)
65         if abs(remainder) > EPSILON:
66             new_p_list.append(remainder)
67         return new_p_list
68 
69     def get_division_along_dimension(self, p_list, dim, colors, vect):
70         p_list = self.complete_p_list(p_list)
71         colors = color_gradient(colors, len(p_list))
72 
73         last_point = self.get_edge_center(-vect)
74         parts = VGroup()
75         for factor, color in zip(p_list, colors):
76             part = SampleSpace()
77             part.set_fill(color, 1)
78             part.replace(self, stretch=True)
79             part.stretch(factor, dim)
80             part.move_to(last_point, -vect)
81             last_point = part.get_edge_center(vect)
82             parts.add(part)
83         return parts
84 
85     def get_horizontal_division(self, p_list, colors=[GREEN_E, BLUE_E], vect=DOWN):
86         return self.get_division_along_dimension(p_list, 1, colors, vect)
87 
88     def get_vertical_division(self, p_list, colors=[MAROON_B, YELLOW], vect=RIGHT):
89         return self.get_division_along_dimension(p_list, 0, colors, vect)
90 
91     def divide_horizontally(self, *args, **kwargs):
92         self.horizontal_parts = self.get_horizontal_division(*args, **kwargs)
93         self.add(self.horizontal_parts)
94 
95     def divide_vertically(self, *args, **kwargs):
96         self.vertical_parts = self.get_vertical_division(*args, **kwargs)
97         self.add(self.vertical_parts)
98 
99     def get_subdivision_braces_and_labels(
100         self, parts, labels, direction, buff=SMALL_BUFF, min_num_quads=1
101     ):
102         label_mobs = VGroup()
103         braces = VGroup()
104         for label, part in zip(labels, parts):
105             brace = Brace(part, direction, min_num_quads=min_num_quads, buff=buff)
106             if isinstance(label, (Mobject, OpenGLMobject)):
107                 label_mob = label
108             else:
109                 label_mob = MathTex(label)
110                 label_mob.scale(self.default_label_scale_val)
111             label_mob.next_to(brace, direction, buff)
112 
113             braces.add(brace)
114             label_mobs.add(label_mob)
115         parts.braces = braces
116         parts.labels = label_mobs
117         parts.label_kwargs = {
118             "labels": label_mobs.copy(),
119             "direction": direction,
120             "buff": buff,
121         }
122         return VGroup(parts.braces, parts.labels)
123 
124     def get_side_braces_and_labels(self, labels, direction=LEFT, **kwargs):
125         assert hasattr(self, "horizontal_parts")
126         parts = self.horizontal_parts
127         return self.get_subdivision_braces_and_labels(
128             parts, labels, direction, **kwargs
129         )
130 
131     def get_top_braces_and_labels(self, labels, **kwargs):
132         assert hasattr(self, "vertical_parts")
133         parts = self.vertical_parts
134         return self.get_subdivision_braces_and_labels(parts, labels, UP, **kwargs)
135 
136     def get_bottom_braces_and_labels(self, labels, **kwargs):
137         assert hasattr(self, "vertical_parts")
138         parts = self.vertical_parts
139         return self.get_subdivision_braces_and_labels(parts, labels, DOWN, **kwargs)
140 
141     def add_braces_and_labels(self):
142         for attr in "horizontal_parts", "vertical_parts":
143             if not hasattr(self, attr):
144                 continue
145             parts = getattr(self, attr)
146             for subattr in "braces", "labels":
147                 if hasattr(parts, subattr):
148                     self.add(getattr(parts, subattr))
149 
150     def __getitem__(self, index):
151         if hasattr(self, "horizontal_parts"):
152             return self.horizontal_parts[index]
153         elif hasattr(self, "vertical_parts"):
154             return self.vertical_parts[index]
155         return self.split()[index]
156 
157 
158 class BarChart(VGroup):
159     def __init__(
160         self,
161         values,
162         height=4,
163         width=6,
164         n_ticks=4,
165         tick_width=0.2,
166         label_y_axis=True,
167         y_axis_label_height=0.25,
168         max_value=1,
169         bar_colors=[BLUE, YELLOW],
170         bar_fill_opacity=0.8,
171         bar_stroke_width=3,
172         bar_names=[],
173         bar_label_scale_val=0.75,
174         **kwargs
175     ):
176         VGroup.__init__(self, **kwargs)
177         self.n_ticks = n_ticks
178         self.tick_width = tick_width
179         self.label_y_axis = label_y_axis
180         self.y_axis_label_height = y_axis_label_height
181         self.max_value = max_value
182         self.bar_colors = bar_colors
183         self.bar_fill_opacity = bar_fill_opacity
184         self.bar_stroke_width = bar_stroke_width
185         self.bar_names = bar_names
186         self.bar_label_scale_val = bar_label_scale_val
187 
188         if self.max_value is None:
189             self.max_value = max(values)
190 
191         self.add_axes(width, height)
192         self.add_bars(values, width, height)
193         self.center()
194 
195     def add_axes(self, width, height):
196         x_axis = Line(self.tick_width * LEFT / 2, width * RIGHT)
197         y_axis = Line(MED_LARGE_BUFF * DOWN, height * UP)
198         ticks = VGroup()
199         heights = np.linspace(0, height, self.n_ticks + 1)
200         values = np.linspace(0, self.max_value, self.n_ticks + 1)
201         for y, _value in zip(heights, values):
202             tick = Line(LEFT, RIGHT)
203             tick.width = self.tick_width
204             tick.move_to(y * UP)
205             ticks.add(tick)
206         y_axis.add(ticks)
207 
208         self.add(x_axis, y_axis)
209         self.x_axis, self.y_axis = x_axis, y_axis
210 
211         if self.label_y_axis:
212             labels = VGroup()
213             for tick, value in zip(ticks, values):
214                 label = MathTex(str(np.round(value, 2)))
215                 label.height = self.y_axis_label_height
216                 label.next_to(tick, LEFT, SMALL_BUFF)
217                 labels.add(label)
218             self.y_axis_labels = labels
219             self.add(labels)
220 
221     def add_bars(self, values, width, height):
222         buff = float(width) / (2 * len(values) + 1)
223         bars = VGroup()
224         for i, value in enumerate(values):
225             bar = Rectangle(
226                 height=(value / self.max_value) * height,
227                 width=buff,
228                 stroke_width=self.bar_stroke_width,
229                 fill_opacity=self.bar_fill_opacity,
230             )
231             bar.move_to((2 * i + 1) * buff * RIGHT, DOWN + LEFT)
232             bars.add(bar)
233         bars.set_color_by_gradient(*self.bar_colors)
234 
235         bar_labels = VGroup()
236         for bar, name in zip(bars, self.bar_names):
237             label = MathTex(str(name))
238             label.scale(self.bar_label_scale_val)
239             label.next_to(bar, DOWN, SMALL_BUFF)
240             bar_labels.add(label)
241 
242         self.add(bars, bar_labels)
243         self.bars = bars
244         self.bar_labels = bar_labels
245 
246     def change_bar_values(self, values):
247         for bar, value in zip(self.bars, values):
248             bar_bottom = bar.get_bottom()
249             bar.stretch_to_fit_height((value / self.max_value) * self.height)
250             bar.move_to(bar_bottom, DOWN)
251
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/manim/mobject/probability.py b/manim/mobject/probability.py
--- a/manim/mobject/probability.py
+++ b/manim/mobject/probability.py
@@ -2,6 +2,7 @@
 
 __all__ = ["SampleSpace", "BarChart"]
 
+import numpy as np
 
 from ..constants import *
 from ..mobject.geometry import Line, Rectangle

{"golden_diff": "diff --git a/manim/mobject/probability.py b/manim/mobject/probability.py\n--- a/manim/mobject/probability.py\n+++ b/manim/mobject/probability.py\n@@ -2,6 +2,7 @@\n \n __all__ = [\"SampleSpace\", \"BarChart\"]\n \n+import numpy as np\n \n from ..constants import *\n from ..mobject.geometry import Line, Rectangle\n", "issue": "numpy not imported in `manim.mobject.probability`\n## Description of bug / unexpected behavior\r\n<!-- Add a clear and concise description of the problem you encountered. -->\r\nWhen you try to use `BarChart` it raises an error saying `np is not defined`\r\n\r\n## Expected behavior\r\n<!-- Add a clear and concise description of what you expected to happen. -->\r\nTo not get the error and show the bar chart.\r\n\r\n## How to reproduce the issue\r\n<!-- Provide a piece of code illustrating the undesired behavior. -->\r\n\r\n<details><summary>Code for reproducing the problem</summary>\r\n\r\n```py\r\nclass Barchart(Scene):\r\n  def construct(self):\r\n    ls = [12,12,13,15,19,20,21]\r\n    bg = BarChart(ls)\r\n    self.add(bg)\r\n```\r\n\r\n</details>\r\n\r\n\r\n## Additional media files\r\n<!-- Paste in the files manim produced on rendering the code above. -->\r\n\r\n<details><summary>Images/GIFs</summary>\r\n\r\n<!-- PASTE MEDIA HERE -->\r\n\r\n</details>\r\n\r\n\r\n## Logs\r\n<details><summary>Terminal output</summary>\r\n<!-- Add \"-v DEBUG\" when calling manim to generate more detailed logs -->\r\n\r\n```\r\n<string> in <module>\r\n\r\n<string> in construct(self)\r\n\r\n/usr/local/lib/python3.7/dist-packages/manim/mobject/probability.py in add_axes(self, width, height)\r\n    197         x_axis = Line(self.tick_width * LEFT / 2, width * RIGHT)\r\n    198         y_axis = Line(MED_LARGE_BUFF * DOWN, height * UP)\r\n--> 199         ticks = VGroup()\r\n    200         heights = np.linspace(0, height, self.n_ticks + 1)\r\n    201         values = np.linspace(0, self.max_value, self.n_ticks + 1)\r\n\r\nNameError: name 'np' is not defined\r\n```\r\n\r\n<!-- Insert screenshots here (only when absolutely necessary, we prefer copy/pasted output!) -->\r\n\r\n</details>\r\n\r\n\r\n## System specifications\r\n\r\n<details><summary>System Details</summary>\r\n\r\n- OS (with version, e.g Windows 10 v2004 or macOS 10.15 (Catalina)):\r\n- RAM:\r\n- Python version (`python/py/python3 --version`):\r\n- Installed modules (provide output from `pip list`):\r\n```\r\nGoogle Colab\r\n```\r\n</details>\r\n\r\n<details><summary>LaTeX details</summary>\r\n\r\n+ LaTeX distribution (e.g. TeX Live 2020):\r\n+ Installed LaTeX packages:\r\n<!-- output of `tlmgr list --only-installed` for TeX Live or a screenshot of the Packages page for MikTeX -->\r\n</details>\r\n\r\n<details><summary>FFMPEG</summary>\r\n\r\nOutput of `ffmpeg -version`:\r\n\r\n```\r\nPASTE HERE\r\n```\r\n</details>\r\n\r\n## Additional comments\r\n<!-- Add further context that you think might be relevant for this issue here. -->\r\n\n", "before_files": [{"content": "\"\"\"Mobjects representing objects from probability theory and statistics.\"\"\"\n\n__all__ = [\"SampleSpace\", \"BarChart\"]\n\n\nfrom ..constants import *\nfrom ..mobject.geometry import Line, Rectangle\nfrom ..mobject.mobject import Mobject\nfrom ..mobject.opengl_mobject import OpenGLMobject\nfrom ..mobject.svg.brace import Brace\nfrom ..mobject.svg.tex_mobject import MathTex, Tex\nfrom ..mobject.types.vectorized_mobject import VGroup\nfrom ..utils.color import (\n    BLUE,\n    BLUE_E,\n    DARK_GREY,\n    GREEN_E,\n    LIGHT_GREY,\n    MAROON_B,\n    YELLOW,\n    color_gradient,\n)\nfrom ..utils.iterables import tuplify\n\nEPSILON = 0.0001\n\n\nclass SampleSpace(Rectangle):\n    def __init__(\n        self,\n        height=3,\n        width=3,\n        fill_color=DARK_GREY,\n        fill_opacity=1,\n        stroke_width=0.5,\n        stroke_color=LIGHT_GREY,\n        default_label_scale_val=1,\n    ):\n        Rectangle.__init__(\n            self,\n            height=height,\n            width=width,\n            fill_color=fill_color,\n            fill_opacity=fill_opacity,\n            stroke_width=stroke_width,\n            stroke_color=stroke_color,\n        )\n        self.default_label_scale_val = default_label_scale_val\n\n    def add_title(self, title=\"Sample space\", buff=MED_SMALL_BUFF):\n        # TODO, should this really exist in SampleSpaceScene\n        title_mob = Tex(title)\n        if title_mob.width > self.width:\n            title_mob.width = self.width\n        title_mob.next_to(self, UP, buff=buff)\n        self.title = title_mob\n        self.add(title_mob)\n\n    def add_label(self, label):\n        self.label = label\n\n    def complete_p_list(self, p_list):\n        new_p_list = list(tuplify(p_list))\n        remainder = 1.0 - sum(new_p_list)\n        if abs(remainder) > EPSILON:\n            new_p_list.append(remainder)\n        return new_p_list\n\n    def get_division_along_dimension(self, p_list, dim, colors, vect):\n        p_list = self.complete_p_list(p_list)\n        colors = color_gradient(colors, len(p_list))\n\n        last_point = self.get_edge_center(-vect)\n        parts = VGroup()\n        for factor, color in zip(p_list, colors):\n            part = SampleSpace()\n            part.set_fill(color, 1)\n            part.replace(self, stretch=True)\n            part.stretch(factor, dim)\n            part.move_to(last_point, -vect)\n            last_point = part.get_edge_center(vect)\n            parts.add(part)\n        return parts\n\n    def get_horizontal_division(self, p_list, colors=[GREEN_E, BLUE_E], vect=DOWN):\n        return self.get_division_along_dimension(p_list, 1, colors, vect)\n\n    def get_vertical_division(self, p_list, colors=[MAROON_B, YELLOW], vect=RIGHT):\n        return self.get_division_along_dimension(p_list, 0, colors, vect)\n\n    def divide_horizontally(self, *args, **kwargs):\n        self.horizontal_parts = self.get_horizontal_division(*args, **kwargs)\n        self.add(self.horizontal_parts)\n\n    def divide_vertically(self, *args, **kwargs):\n        self.vertical_parts = self.get_vertical_division(*args, **kwargs)\n        self.add(self.vertical_parts)\n\n    def get_subdivision_braces_and_labels(\n        self, parts, labels, direction, buff=SMALL_BUFF, min_num_quads=1\n    ):\n        label_mobs = VGroup()\n        braces = VGroup()\n        for label, part in zip(labels, parts):\n            brace = Brace(part, direction, min_num_quads=min_num_quads, buff=buff)\n            if isinstance(label, (Mobject, OpenGLMobject)):\n                label_mob = label\n            else:\n                label_mob = MathTex(label)\n                label_mob.scale(self.default_label_scale_val)\n            label_mob.next_to(brace, direction, buff)\n\n            braces.add(brace)\n            label_mobs.add(label_mob)\n        parts.braces = braces\n        parts.labels = label_mobs\n        parts.label_kwargs = {\n            \"labels\": label_mobs.copy(),\n            \"direction\": direction,\n            \"buff\": buff,\n        }\n        return VGroup(parts.braces, parts.labels)\n\n    def get_side_braces_and_labels(self, labels, direction=LEFT, **kwargs):\n        assert hasattr(self, \"horizontal_parts\")\n        parts = self.horizontal_parts\n        return self.get_subdivision_braces_and_labels(\n            parts, labels, direction, **kwargs\n        )\n\n    def get_top_braces_and_labels(self, labels, **kwargs):\n        assert hasattr(self, \"vertical_parts\")\n        parts = self.vertical_parts\n        return self.get_subdivision_braces_and_labels(parts, labels, UP, **kwargs)\n\n    def get_bottom_braces_and_labels(self, labels, **kwargs):\n        assert hasattr(self, \"vertical_parts\")\n        parts = self.vertical_parts\n        return self.get_subdivision_braces_and_labels(parts, labels, DOWN, **kwargs)\n\n    def add_braces_and_labels(self):\n        for attr in \"horizontal_parts\", \"vertical_parts\":\n            if not hasattr(self, attr):\n                continue\n            parts = getattr(self, attr)\n            for subattr in \"braces\", \"labels\":\n                if hasattr(parts, subattr):\n                    self.add(getattr(parts, subattr))\n\n    def __getitem__(self, index):\n        if hasattr(self, \"horizontal_parts\"):\n            return self.horizontal_parts[index]\n        elif hasattr(self, \"vertical_parts\"):\n            return self.vertical_parts[index]\n        return self.split()[index]\n\n\nclass BarChart(VGroup):\n    def __init__(\n        self,\n        values,\n        height=4,\n        width=6,\n        n_ticks=4,\n        tick_width=0.2,\n        label_y_axis=True,\n        y_axis_label_height=0.25,\n        max_value=1,\n        bar_colors=[BLUE, YELLOW],\n        bar_fill_opacity=0.8,\n        bar_stroke_width=3,\n        bar_names=[],\n        bar_label_scale_val=0.75,\n        **kwargs\n    ):\n        VGroup.__init__(self, **kwargs)\n        self.n_ticks = n_ticks\n        self.tick_width = tick_width\n        self.label_y_axis = label_y_axis\n        self.y_axis_label_height = y_axis_label_height\n        self.max_value = max_value\n        self.bar_colors = bar_colors\n        self.bar_fill_opacity = bar_fill_opacity\n        self.bar_stroke_width = bar_stroke_width\n        self.bar_names = bar_names\n        self.bar_label_scale_val = bar_label_scale_val\n\n        if self.max_value is None:\n            self.max_value = max(values)\n\n        self.add_axes(width, height)\n        self.add_bars(values, width, height)\n        self.center()\n\n    def add_axes(self, width, height):\n        x_axis = Line(self.tick_width * LEFT / 2, width * RIGHT)\n        y_axis = Line(MED_LARGE_BUFF * DOWN, height * UP)\n        ticks = VGroup()\n        heights = np.linspace(0, height, self.n_ticks + 1)\n        values = np.linspace(0, self.max_value, self.n_ticks + 1)\n        for y, _value in zip(heights, values):\n            tick = Line(LEFT, RIGHT)\n            tick.width = self.tick_width\n            tick.move_to(y * UP)\n            ticks.add(tick)\n        y_axis.add(ticks)\n\n        self.add(x_axis, y_axis)\n        self.x_axis, self.y_axis = x_axis, y_axis\n\n        if self.label_y_axis:\n            labels = VGroup()\n            for tick, value in zip(ticks, values):\n                label = MathTex(str(np.round(value, 2)))\n                label.height = self.y_axis_label_height\n                label.next_to(tick, LEFT, SMALL_BUFF)\n                labels.add(label)\n            self.y_axis_labels = labels\n            self.add(labels)\n\n    def add_bars(self, values, width, height):\n        buff = float(width) / (2 * len(values) + 1)\n        bars = VGroup()\n        for i, value in enumerate(values):\n            bar = Rectangle(\n                height=(value / self.max_value) * height,\n                width=buff,\n                stroke_width=self.bar_stroke_width,\n                fill_opacity=self.bar_fill_opacity,\n            )\n            bar.move_to((2 * i + 1) * buff * RIGHT, DOWN + LEFT)\n            bars.add(bar)\n        bars.set_color_by_gradient(*self.bar_colors)\n\n        bar_labels = VGroup()\n        for bar, name in zip(bars, self.bar_names):\n            label = MathTex(str(name))\n            label.scale(self.bar_label_scale_val)\n            label.next_to(bar, DOWN, SMALL_BUFF)\n            bar_labels.add(label)\n\n        self.add(bars, bar_labels)\n        self.bars = bars\n        self.bar_labels = bar_labels\n\n    def change_bar_values(self, values):\n        for bar, value in zip(self.bars, values):\n            bar_bottom = bar.get_bottom()\n            bar.stretch_to_fit_height((value / self.max_value) * self.height)\n            bar.move_to(bar_bottom, DOWN)\n", "path": "manim/mobject/probability.py"}], "after_files": [{"content": "\"\"\"Mobjects representing objects from probability theory and statistics.\"\"\"\n\n__all__ = [\"SampleSpace\", \"BarChart\"]\n\nimport numpy as np\n\nfrom ..constants import *\nfrom ..mobject.geometry import Line, Rectangle\nfrom ..mobject.mobject import Mobject\nfrom ..mobject.opengl_mobject import OpenGLMobject\nfrom ..mobject.svg.brace import Brace\nfrom ..mobject.svg.tex_mobject import MathTex, Tex\nfrom ..mobject.types.vectorized_mobject import VGroup\nfrom ..utils.color import (\n    BLUE,\n    BLUE_E,\n    DARK_GREY,\n    GREEN_E,\n    LIGHT_GREY,\n    MAROON_B,\n    YELLOW,\n    color_gradient,\n)\nfrom ..utils.iterables import tuplify\n\nEPSILON = 0.0001\n\n\nclass SampleSpace(Rectangle):\n    def __init__(\n        self,\n        height=3,\n        width=3,\n        fill_color=DARK_GREY,\n        fill_opacity=1,\n        stroke_width=0.5,\n        stroke_color=LIGHT_GREY,\n        default_label_scale_val=1,\n    ):\n        Rectangle.__init__(\n            self,\n            height=height,\n            width=width,\n            fill_color=fill_color,\n            fill_opacity=fill_opacity,\n            stroke_width=stroke_width,\n            stroke_color=stroke_color,\n        )\n        self.default_label_scale_val = default_label_scale_val\n\n    def add_title(self, title=\"Sample space\", buff=MED_SMALL_BUFF):\n        # TODO, should this really exist in SampleSpaceScene\n        title_mob = Tex(title)\n        if title_mob.width > self.width:\n            title_mob.width = self.width\n        title_mob.next_to(self, UP, buff=buff)\n        self.title = title_mob\n        self.add(title_mob)\n\n    def add_label(self, label):\n        self.label = label\n\n    def complete_p_list(self, p_list):\n        new_p_list = list(tuplify(p_list))\n        remainder = 1.0 - sum(new_p_list)\n        if abs(remainder) > EPSILON:\n            new_p_list.append(remainder)\n        return new_p_list\n\n    def get_division_along_dimension(self, p_list, dim, colors, vect):\n        p_list = self.complete_p_list(p_list)\n        colors = color_gradient(colors, len(p_list))\n\n        last_point = self.get_edge_center(-vect)\n        parts = VGroup()\n        for factor, color in zip(p_list, colors):\n            part = SampleSpace()\n            part.set_fill(color, 1)\n            part.replace(self, stretch=True)\n            part.stretch(factor, dim)\n            part.move_to(last_point, -vect)\n            last_point = part.get_edge_center(vect)\n            parts.add(part)\n        return parts\n\n    def get_horizontal_division(self, p_list, colors=[GREEN_E, BLUE_E], vect=DOWN):\n        return self.get_division_along_dimension(p_list, 1, colors, vect)\n\n    def get_vertical_division(self, p_list, colors=[MAROON_B, YELLOW], vect=RIGHT):\n        return self.get_division_along_dimension(p_list, 0, colors, vect)\n\n    def divide_horizontally(self, *args, **kwargs):\n        self.horizontal_parts = self.get_horizontal_division(*args, **kwargs)\n        self.add(self.horizontal_parts)\n\n    def divide_vertically(self, *args, **kwargs):\n        self.vertical_parts = self.get_vertical_division(*args, **kwargs)\n        self.add(self.vertical_parts)\n\n    def get_subdivision_braces_and_labels(\n        self, parts, labels, direction, buff=SMALL_BUFF, min_num_quads=1\n    ):\n        label_mobs = VGroup()\n        braces = VGroup()\n        for label, part in zip(labels, parts):\n            brace = Brace(part, direction, min_num_quads=min_num_quads, buff=buff)\n            if isinstance(label, (Mobject, OpenGLMobject)):\n                label_mob = label\n            else:\n                label_mob = MathTex(label)\n                label_mob.scale(self.default_label_scale_val)\n            label_mob.next_to(brace, direction, buff)\n\n            braces.add(brace)\n            label_mobs.add(label_mob)\n        parts.braces = braces\n        parts.labels = label_mobs\n        parts.label_kwargs = {\n            \"labels\": label_mobs.copy(),\n            \"direction\": direction,\n            \"buff\": buff,\n        }\n        return VGroup(parts.braces, parts.labels)\n\n    def get_side_braces_and_labels(self, labels, direction=LEFT, **kwargs):\n        assert hasattr(self, \"horizontal_parts\")\n        parts = self.horizontal_parts\n        return self.get_subdivision_braces_and_labels(\n            parts, labels, direction, **kwargs\n        )\n\n    def get_top_braces_and_labels(self, labels, **kwargs):\n        assert hasattr(self, \"vertical_parts\")\n        parts = self.vertical_parts\n        return self.get_subdivision_braces_and_labels(parts, labels, UP, **kwargs)\n\n    def get_bottom_braces_and_labels(self, labels, **kwargs):\n        assert hasattr(self, \"vertical_parts\")\n        parts = self.vertical_parts\n        return self.get_subdivision_braces_and_labels(parts, labels, DOWN, **kwargs)\n\n    def add_braces_and_labels(self):\n        for attr in \"horizontal_parts\", \"vertical_parts\":\n            if not hasattr(self, attr):\n                continue\n            parts = getattr(self, attr)\n            for subattr in \"braces\", \"labels\":\n                if hasattr(parts, subattr):\n                    self.add(getattr(parts, subattr))\n\n    def __getitem__(self, index):\n        if hasattr(self, \"horizontal_parts\"):\n            return self.horizontal_parts[index]\n        elif hasattr(self, \"vertical_parts\"):\n            return self.vertical_parts[index]\n        return self.split()[index]\n\n\nclass BarChart(VGroup):\n    def __init__(\n        self,\n        values,\n        height=4,\n        width=6,\n        n_ticks=4,\n        tick_width=0.2,\n        label_y_axis=True,\n        y_axis_label_height=0.25,\n        max_value=1,\n        bar_colors=[BLUE, YELLOW],\n        bar_fill_opacity=0.8,\n        bar_stroke_width=3,\n        bar_names=[],\n        bar_label_scale_val=0.75,\n        **kwargs\n    ):\n        VGroup.__init__(self, **kwargs)\n        self.n_ticks = n_ticks\n        self.tick_width = tick_width\n        self.label_y_axis = label_y_axis\n        self.y_axis_label_height = y_axis_label_height\n        self.max_value = max_value\n        self.bar_colors = bar_colors\n        self.bar_fill_opacity = bar_fill_opacity\n        self.bar_stroke_width = bar_stroke_width\n        self.bar_names = bar_names\n        self.bar_label_scale_val = bar_label_scale_val\n\n        if self.max_value is None:\n            self.max_value = max(values)\n\n        self.add_axes(width, height)\n        self.add_bars(values, width, height)\n        self.center()\n\n    def add_axes(self, width, height):\n        x_axis = Line(self.tick_width * LEFT / 2, width * RIGHT)\n        y_axis = Line(MED_LARGE_BUFF * DOWN, height * UP)\n        ticks = VGroup()\n        heights = np.linspace(0, height, self.n_ticks + 1)\n        values = np.linspace(0, self.max_value, self.n_ticks + 1)\n        for y, _value in zip(heights, values):\n            tick = Line(LEFT, RIGHT)\n            tick.width = self.tick_width\n            tick.move_to(y * UP)\n            ticks.add(tick)\n        y_axis.add(ticks)\n\n        self.add(x_axis, y_axis)\n        self.x_axis, self.y_axis = x_axis, y_axis\n\n        if self.label_y_axis:\n            labels = VGroup()\n            for tick, value in zip(ticks, values):\n                label = MathTex(str(np.round(value, 2)))\n                label.height = self.y_axis_label_height\n                label.next_to(tick, LEFT, SMALL_BUFF)\n                labels.add(label)\n            self.y_axis_labels = labels\n            self.add(labels)\n\n    def add_bars(self, values, width, height):\n        buff = float(width) / (2 * len(values) + 1)\n        bars = VGroup()\n        for i, value in enumerate(values):\n            bar = Rectangle(\n                height=(value / self.max_value) * height,\n                width=buff,\n                stroke_width=self.bar_stroke_width,\n                fill_opacity=self.bar_fill_opacity,\n            )\n            bar.move_to((2 * i + 1) * buff * RIGHT, DOWN + LEFT)\n            bars.add(bar)\n        bars.set_color_by_gradient(*self.bar_colors)\n\n        bar_labels = VGroup()\n        for bar, name in zip(bars, self.bar_names):\n            label = MathTex(str(name))\n            label.scale(self.bar_label_scale_val)\n            label.next_to(bar, DOWN, SMALL_BUFF)\n            bar_labels.add(label)\n\n        self.add(bars, bar_labels)\n        self.bars = bars\n        self.bar_labels = bar_labels\n\n    def change_bar_values(self, values):\n        for bar, value in zip(self.bars, values):\n            bar_bottom = bar.get_bottom()\n            bar.stretch_to_fit_height((value / self.max_value) * self.height)\n            bar.move_to(bar_bottom, DOWN)\n", "path": "manim/mobject/probability.py"}]}