ManimをGoogle Colabで動かす、Pythonで美しい数式アニメーションを作る




# 1. はじめに

<div class="columns">
<div class="column">

### この動画について
この動画では、数式や概念を美しく視覚化できるPythonライブラリ「Manim」を、環境構築が簡単な「Google Colaboratory (Colab)」上で実行する方法を解説します。

<iframe width="560" height="315" src="https://www.youtube.com/embed/Ga5Eqh45k9w?si=PHOz5-qTnmS4CKM-" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

</div>
<div class="column">

### メリット（概要）
ローカル環境を汚さずに、ブラウザだけで高度な数学アニメーション（2Dおよび3D）の作成を始められます。



</div>
</div>

---

## 対象読者とゴール

<div class="columns">
<div class="column">

### 対象読者

*   Manimに興味があるけれど、環境構築が難しそうだと感じている方
*   手軽にManimを試してみたいPythonユーザー
*   数学や物理の概念を視覚的に伝えたい教育関係者
*   プログラミングでクリエイティブな表現をしたい方

</div>
<div class="column">

### この動画で学べること

*   Google Colab上でのManim環境構築
*   2Dアニメーションの作成と表示
*   3Dアニメーションの作成と表示
*   Manimの基本的なコード構造の理解


</div>
</div>

---

# 2. なぜGoogle ColabでManimなのか？

## ManimとColabの概要

<div class="columns">
<div class="column">

### Manimとは？

3Blue1Brownでも利用されている、高品質な数学アニメーションを作成するためのPythonライブラリです。

*   **数式の美しさ**: LaTeXと連携
*   **柔軟なアニメーション**: コードで細かく制御
*   **豊富なオブジェクト**: 図形、グラフ、3Dなど
*   **活発なコミュニティ**: Manim Community Editionが主流

</div>
<div class="column">

### Google Colabとは？

Googleが提供する無料のクラウドベースのJupyter Notebook環境です。

*   ブラウザ上でPythonを実行
*   ライブラリのインストールが容易
*   Google Driveと連携


</div>
</div>

---

# Google ColabでManimを使う強力なメリット

## 以下のような大きな利点があります。

<div class="columns">
<div class="column">

*   **環境構築が圧倒的に楽！**: Colabなら数コマンドで準備が完了し、ローカルPCの環境を汚しません。
*   **どこでもアクセス可能**: Googleアカウントとブラウザさえあれば、どのPCからでも作業を再開できます。
*   **無料で利用可能**: 基本的な機能は無料で、Manimの学習や小規模なプロジェクトには十分です。

</div>
<div class="column">

*   **Google Driveとの連携**: 作成したスクリプトや動画は、簡単にGoogle Driveに保存・同期できます。
*   **共有が容易**: 作成したColabノートブックは、リンク一つで他の人と簡単に共有できます。

</div>
</div>

---

# 3. Google Colabでの作成手順

## ステップ1: 環境構築

<div class="columns">
<div class="column">

### ① ライブラリのインストール
以下のコマンドでManimとその依存関係をインストールします。

```python
# パッケージリストを更新
!sudo apt update
# 必要なライブラリをインストール
!sudo apt install libcairo2-dev \
    texlive texlive-latex-extra \
    texlive-fonts-extra \
    texlive-latex-recommended \
    texlive-science tipa \
    libpango1.0-dev
# ManimとIPythonをインストール
!pip install manim
!pip install IPython==8.21.0
```

※*Manim Community v0.19.0で公開されているコード*

</div>
<div class="column">

### ② ランタイムの再起動
インストール完了後、変更を反映させるために、メニューの「ランタイム」 > 「ランタイムを再起動」を選択してください。

### ③ 日本語フォントのインストール
アニメーション内で日本語を表示するためのフォントをインストールします。
```python
!apt-get update
!apt-get install -y fonts-noto-cjk
```
これで環境構築は完了です。

</div>
</div>

---

# 3. Google Colabでの作成手順
## ステップ2, 3 : スクリプト作成と動画生成

<div class="columns">
<div class="column">

### ステップ2: スクリプト作成
`%%writefile`マジックコマンドで、Manimのアニメーションを定義するPythonファイルを作成します。

```python:例
%%writefile my_animation.py
from manim import *

class MyScene(Scene):
    def construct(self):
        circle = Circle()
        self.play(Create(circle))
        self.wait()
```

</div>
<div class="column">

### ステップ3: 動画生成・表示
以下のコードで、作成したスクリプトから動画を生成し、Colab上に表示します。

```python
import os
from IPython.display import Video, display

# --- ユーザー設定項目 ---
PYTHON_FILE = "my_animation.py"  # ManimのPythonスクリプトファイル名
SCENE_NAME = "MyScene"                 # レンダリングするシーン名 (ファイル全体なら "" または None)

# Manimのレンダリングオプション
# 品質フラグ例: "-pql" (480p15), "-pqm" (720p30), "-pqh" (1080p60), "-pqk" (2160p60)
MANIM_FLAGS = "-pql"

# レンダリング前に出力ディレクトリをクリーンアップするか
CLEAN_OUTPUT_BEFORE_RENDER = False

# Manimの出力ビデオのベースディレクトリ
# Google Colabの場合
BASE_VIDEO_DIR = "/content/media/videos"

# 動画ファイルの拡張子 (通常は変更不要)
VIDEO_EXTENSION = ".mp4"

# (オプション) 動画の解像度とFPSの手動オーバーライド
# 通常、これらはMANIM_FLAGSから自動判別されます。
# 特定の値を強制したい場合のみ、None以外の値を設定してください。
OVERRIDE_VIDEO_HEIGHT = None  # 例: 720
OVERRIDE_VIDEO_FPS = None     # 例: 30



# --- 内部設定 & 導出変数 ---
SCRIPT_FILE_BASENAME = os.path.splitext(PYTHON_FILE)[0]

# Manim品質フラグと対応する解像度・FPSの辞書
# Manim v0.18.0以降の -q l/m/h/k や、それ以前の -ql/-qm/-qh/-qk, -pql/-pqm/-pqh/-pqk に対応
QUALITY_TO_RES_FPS = {
    "-pql": (480, 15), "l": (480, 15), "-ql": (480, 15),
    "-pqm": (720, 30), "m": (720, 30), "-qm": (720, 30),
    "-pqh": (1080, 60), "h": (1080, 60), "-qh": (1080, 60),
    "-pqk": (2160, 60), "k": (2160, 60), "-qk": (2160, 60),
}

# MANIM_FLAGSから主要な品質フラグを抽出
parsed_quality_flag = None
for flag_part in MANIM_FLAGS.split():
    if flag_part in QUALITY_TO_RES_FPS:
        parsed_quality_flag = flag_part
        break

# VIDEO_HEIGHT と VIDEO_FPS を決定
# まずオーバーライド値を確認
video_height = OVERRIDE_VIDEO_HEIGHT
video_fps = OVERRIDE_VIDEO_FPS

# オーバーライド値がなければ、MANIM_FLAGSから導出した値を使用
if video_height is None or video_fps is None: # 片方だけオーバーライドされた場合も考慮
    derived_h, derived_f = None, None
    if parsed_quality_flag:
        derived_h, derived_f = QUALITY_TO_RES_FPS[parsed_quality_flag]
    
    if video_height is None: # OVERRIDE_VIDEO_HEIGHT が None の場合のみ、導出値で埋める
        video_height = derived_h
    if video_fps is None:    # OVERRIDE_VIDEO_FPS が None の場合のみ、導出値で埋める
        video_fps = derived_f

# --- 処理実行 ---

# 1. (オプション) 既存の出力ディレクトリを削除
if CLEAN_OUTPUT_BEFORE_RENDER:
    # Google Colabの典型的なパス "/content/media/videos" の場合、削除対象は "/content/media"
    # それ以外の場合 (ローカル環境など)、カレントディレクトリ直下の "media" フォルダを対象とする
    if BASE_VIDEO_DIR == "/content/media/videos":
        path_to_remove = "/content/media"
    else:
        path_to_remove = "media" # カレントディレクトリの 'media'
    
    print(f"既存の出力ディレクトリ '{path_to_remove}' を削除します...")
    get_ipython().system(f"rm -rf {path_to_remove}")

# 2. Manimコマンドの組み立てと実行
command_parts = ["manim", MANIM_FLAGS, PYTHON_FILE]
# SCENE_NAME が指定されている場合のみコマンドに追加 (空文字列やNoneは除く)
if SCENE_NAME and SCENE_NAME.strip():
    command_parts.append(SCENE_NAME)

# filter(None,...)で空要素を除去し、余分なスペースも除去してコマンド文字列を生成
manim_command = " ".join(filter(None, command_parts)).strip()

print(f"\n実行するManimコマンド: {manim_command}\n")

# Manimコマンドを実行
get_ipython().system(manim_command)

print("\nレンダリング処理が完了しました。")


# 3. 動画パスの組み立てと表示
if video_height is None or video_fps is None:
    print("\n動画の解像度またはFPSが特定できませんでした。")

elif not SCENE_NAME or not SCENE_NAME.strip():
    print("\n警告: SCENE_NAME が指定されていません。")

else:
    quality_directory_name = f"{video_height}p{video_fps}"
    
    video_file_path = os.path.join(
        BASE_VIDEO_DIR,
        SCRIPT_FILE_BASENAME,
        quality_directory_name,
        f"{SCENE_NAME}{VIDEO_EXTENSION}"
    )

    print(f"\n表示しようとしている動画パス: {video_file_path}")
    if os.path.exists(video_file_path):
        try:
            display(Video(video_file_path, embed=True, width=1000)) # widthはお好みで調整
        except Exception as e:
            print(f"動画表示中にエラーが発生しました: {e}")
            print(f"動画ファイルパス: {video_file_path}")
    else:
        print(f"エラー: 動画ファイルが見つかりません: {video_file_path}")



```

</div>
</div>

---

# 3. Google Colabでの作成手順
## (発展) 3Dアニメーションの作成

<div class="columns">
<div class="column">

### 3Dシーンのスクリプト例
`ThreeDScene`を継承し、3Dオブジェクトやカメラ操作を使ってアニメーションを作成します。

```python
# 例
%%writefile basic_3d.py
from manim import *

class Basic3D(ThreeDScene):
  def construct(self):
    self.set_camera_orientation(
        phi=75*DEGREES, theta=30*DEGREES)
    axes = ThreeDAxes()
    sphere = Sphere(radius=1.5)
    self.play(Create(axes), Create(sphere))
    self.wait()
```

</div>
<div class="column">

### 注意点：解像度とレンダリング時間
*   **`resolution`**: 3Dオブジェクトの滑らかさを決めるパラメータです。
*   **レンダリング時間**: `resolution`の値を大きくすると、計算量が増加し、レンダリング時間が長くなる可能性があります。
*   **Colabでの推奨**:
    1.  最初は低い`resolution`でテストする。
    2.  全体の構成が決まったら、徐々に値を上げて品質を調整する。

</div>
</div>

---

# 4. Manimコード基本要素

## SceneとMobject / self.play()と.animate

<div class="columns">
<div class="column">

### `Scene`と`Mobject`
*   **`Scene` / `ThreeDScene`**:
    アニメーションの舞台となるクラス。`construct`メソッド内にロジックを記述します。
*   **`Mobject` (Manim Object)**:
    画面上の全ての要素（図形、テキスト、数式など）。
    *   `Circle()`, `Square()`
    *   位置 `.move_to()`、サイズ `.scale()`、色 `.set_color()` などをメソッドで操作します。

</div>
<div class="column">

### `self.play()`と`.animate`
*   **`self.play(animation_type)`**:
    アニメーションを実際に再生する命令です。
    *   `Create(obj)`, `FadeIn(obj)`
    *   `Transform(obj1, obj2)`
*   **`.animate`構文**:
    Mobjectのプロパティをアニメーション付きで変更する直感的な方法です。
    ```python
    # 2秒かけて円を右に動かす
    self.play(
      my_circle.animate.shift(RIGHT),
      run_time=2
    )
    ```
</div>
</div>


---
# 4. Manimコード基本要素

## MathTexとVGroup / Transform

<div class="columns">
<div class="column">

### `MathTex` と `VGroup`
*   **`MathTex("x^2")`**:
    LaTeXで数式を描画。`r""` (raw string) でエスケープ不要。
*   **`Text("こんにちは")`**:
    テキストを描画。日本語フォント指定で日本語表示可能。
*   **`VGroup(obj1, obj2)`**:
    複数のMobjectをグループ化。
    移動やアニメーションをまとめて操作。
    `.arrange()` で整列可能。

</div>
<div class="column">

### `Transform`

*   **`Transform(A, B)`**:
    AがBの**特性**（形、色、位置など）に変化します。アニメーション後、**Aは変形した姿でシーンに残り**、Bは変形の目標として使われます。
*   **`ReplacementTransform(A, B)`**:
    あるオブジェクトが別のオブジェクトに**置き換わる**ように滑らかに変化します。アニメーション後、**Aはシーンから消え、Bの特性に変化したものがシーンに残ります**。




</div>
</div>



---

# 4. Manimコード基本要素

## `add_updater` と `ValueTracker`

<div class="columns">
<div class="column">

*   **`ValueTracker(initial_value)`**:
    *   アニメーションの進行に合わせて変化する「数値」を管理します。
    *   `.animate.set_value(target_value)` で値を滑らかに変化させられます。



</div>
<div class="column">

*   **`object.add_updater(lambda mob: ...)`**:
    *   `object` にアップデーター関数を登録します。
    *   この関数は毎フレーム呼び出され、`object` の見た目を更新し続けます。
    *   `ValueTracker` の値に応じてオブジェクトの位置や形を動的に変えたい場合などに非常に強力です。

</div>
</div>

---

# 4. Manimコード基本要素
## 3D関連オブジェクト

<div class="columns">
<div class="column">

*   **`ThreeDAxes()`**: 3Dの座標軸を作成します。

*   **基本的な3D図形**:
    <div class="nested-list">
    <ul>
        <li>`Sphere()` (球)</li>
        <li>`Cube()` (立方体)</li>
        <li>`Cylinder()` (円柱)</li>
        <li>`Cone()` (円錐)</li>
    </ul>
    </div>

</div>
<div class="column">

*   **`Surface(function, u_range, v_range, resolution)`**:
    *   パラメトリック関数から3D曲面を生成します。
    <div class="nested-list">
    <ul>
        <li>`function`: (u, v) を引数とし、[x, y, z] 座標を返す関数。</li>
        <li>`u_range`, `v_range`: uとvの範囲 (例: `[0, PI]`)。</li>
        <li>`resolution`: 曲面の滑らかさ (タプルで指定、例: `(24, 24)`)。</li>
    </ul>
    </div>
</div>
</div>

---

# 4. Manimコード基本要素
## カメラ操作

<div class="columns">
<div class="column">

*   **`self.set_camera_orientation(...)`**:
カメラの**位置（角度と距離を含む）**、**向き（ロール）**、**注視点**、**ズーム**を設定します。


    *   `phi`: **Z軸からの傾き**（極角）。
    *   `theta`: **Z軸周りの回転**（方位角）。
    *   `gamma`: **視線周りの回転**（ロール角）。
    *   `focal_distance`: **カメラと注視点の距離**。
    *   `frame_center`: **カメラが見る中心点**（注視点）。
    *   `zoom`: **シーンの拡大・縮小率**。

</div>
<div class="column">

*   **`self.move_camera(...)`**:
    *   カメラを移動・回転させます。 (例: `phi`, `theta`, `focal_point`, `zoom` などをキーワード引数で指定)

*   **`self.begin_ambient_camera_rotation(rate, about)`**:
    *   カメラを自動で回転させ続けます。
    *   `rate`: 回転速度 (例: `0.1` rad/秒)
    *   `about`: 回転の中心軸 (`'phi'`, `'theta'`, または `'gamma'`)

</div>
</div>


---

# 5. 補足と注意事項

## 動画のダウンロード方法 / エラーが発生した場合

<div class="columns">
<div class="column">

### 動画のダウンロード方法
Manimでレンダリングされた動画ファイル（.mp4）は、Colabの左側にあるファイルブラウザパネルからダウンロードできます。

**パスの例**:
`media/videos/{スクリプト名}/{品質フォルダ}/{シーン名}.mp4`

</div>
<div class="column">

### エラーが発生した場合
エラーメッセージをよく読み、原因を特定しましょう。

*   **Python構文エラー**:
    `%%writefile`で保存したスクリプトを確認。
*   **LaTeXのエラー**:
    `MathTex`内の数式表現が正しいか確認。
*   **ファイル名・シーン名の不一致**:
    動画生成コードの`PYTHON_FILE`や`SCENE_NAME`の指定が正しいか確認。

</div>
</div>

---

# 6. おわりに

この動画では、Google Colaboratory を使ってManimの環境を構築し、2Dおよび3Dの数学アニメーションを作成する手順を紹介しました。

Colabの手軽さを活用すれば、複雑なセットアップに悩まされることなく、すぐにManimのパワフルな表現力を体験できます。

ぜひ、様々なリソースも活用して、Manimの世界をさらに探求してみてください。