Python Turtleとは?初心者向けグラフィックプログラミング入門

2025-06-06

Pythonのturtleモジュールは、グラフィック描画を簡単に行うためのモジュールです。Logoプログラミング言語にインスパイアされており、"タートル"と呼ばれる小さなカーソルを動かすことで線や図形を描くことができます。

そして、turtledemoは、このturtleモジュールの使い方を示すデモスクリプト集です。これはPythonの標準ライブラリの一部として含まれており、turtleモジュールの様々な機能や、それを使ってどのような面白いグラフィックが描けるかを示すためのたくさんのサンプルプログラムが用意されています。

turtledemoの目的

turtledemoの主な目的は以下の通りです。

  1. 学習の補助: turtleモモジュールが提供する描画コマンド(例: forward(), left(), right(), circle(), color(), penup(), pendown()など)の動作を視覚的に理解するのに役立ちます。
  2. インスピレーション: どのような種類のグラフィックやアニメーションをturtleで作成できるかを示すことで、ユーザー自身の創造性を刺激します。
  3. コードの例: 実際の描画スクリプトの例として、どのようにコードを記述すれば良いかのヒントを提供します。

turtledemoの実行方法

通常、turtledemoはPythonのインストールディレクトリ内のLib/turtledemoにあります。これら個々のデモスクリプトは、通常のPythonスクリプトと同様に実行できます。

コマンドラインから特定のデモを実行する例:

python -m turtledemo.bytedesign

または、PythonのIDLEやエディタでこれらのスクリプトを開いて実行することもできます。

turtledemoを実行すると、通常、turtleグラフィックウィンドウが開き、デモスクリプトが描画を開始します。例えば、美しい幾何学模様、らせん、カラフルなパターン、あるいは簡単なアニメーションなどが表示されます。

turtledemoに含まれるデモの例 (一部)

turtledemoには様々な種類のデモが含まれており、それぞれ異なる描画技術やアルゴリズムを示しています。いくつか例を挙げると:

  • paint.py: 簡単なペイントアプリケーションのように、ユーザーがマウスで描画できるデモです。
  • chaos.py: カオス理論に関連する図形を描きます。
  • bytedesign.py: カラフルで動きのあるデザインを描きます。
  • lindenmayer.py: L-システム(植物の成長などをシミュレートするシステム)を使って複雑なパターンを描きます。
  • fractal.py: フラクタル図形を描きます。


turtledemoturtleモジュール自体は比較的シンプルですが、実行環境やコードの書き方によっては問題が発生することがあります。

ModuleNotFoundError: No module named '_tkinter'

エラーの原因
turtleモジュールは、グラフィック描画のためにTkinterというGUIライブラリに依存しています。このエラーは、システムにTkinterが正しくインストールされていないか、Pythonのインストール時にTkinterのサポートが含まれていなかった場合に発生します。特に、Linuxディストリビューションでは、PythonをインストールしてもTkinterがデフォルトで含まれていないことがあります。

トラブルシューティング

  • Windows/macOSの場合
    Pythonの公式インストーラーを使用していれば、通常Tkinterは含まれています。もしこのエラーが出る場合は、Pythonの再インストールを検討し、インストールオプションで「Tkinter」が選択されていることを確認してください。
  • Linuxの場合
    tkinterは通常、python3-tk(Python 3の場合)やpython-tk(Python 2の場合)といったパッケージ名で提供されています。お使いのパッケージマネージャー(例: apt, yum, dnf)を使ってインストールしてください。
    # Debian/Ubuntu系
    sudo apt-get update
    sudo apt-get install python3-tk
    
    # Fedora/CentOS系
    sudo dnf install python3-tkinter
    # または sudo yum install python3-tkinter
    

ウィンドウが表示されない、またはすぐに閉じてしまう

エラーの原因
turtleグラフィックウィンドウが表示されてもすぐに閉じてしまう、またはまったく表示されない場合があります。これは、スクリプトが描画を完了した後に、ウィンドウを維持するためのコマンドが不足している場合に発生することが多いです。

トラブルシューティング

  • コマンドラインからの実行
    IDLEなどの統合開発環境で実行していると、エラーメッセージがすぐに見えずにウィンドウが閉じてしまうことがあります。コマンドプロンプトやターミナルから直接スクリプトを実行すると、エラーメッセージがコンソールに表示され、問題の特定に役立ちます。
    python -m turtledemo.bytedesign
    
  • turtle.done() または turtle.mainloop() の追加
    turtleプログラムが描画を終えた後もウィンドウを開いたままにするには、スクリプトの最後にturtle.done()またはturtle.mainloop()(または単にdone()mainloop()もしfrom turtle import *を使っている場合)を追加する必要があります。これにより、ユーザーが手動でウィンドウを閉じるまでプログラムが待機します。turtledemoのスクリプトは通常これらを含んでいますが、自分でturtleプログラムを書く際には注意が必要です。
    import turtle
    
    # 描画コード
    turtle.forward(100)
    turtle.left(90)
    turtle.forward(100)
    
    # ウィンドウを閉じずに待機
    turtle.done()
    

NameError: name 'turtle' is not defined または NameError: name 'forward' is not defined

エラーの原因
turtleモジュールが正しくインポートされていないか、関数やオブジェクトの呼び出し方が間違っている場合に発生します。

トラブルシューティング

  • スペルミス
    関数名や変数名のスペルが間違っていないか確認してください。
  • 正しいインポート
    プログラムの冒頭でimport turtleと記述しているか確認してください。 もしimport turtleを使っている場合、turtle.forward(100)のように、turtle.プレフィックスを付けて関数を呼び出す必要があります。
    import turtle
    turtle.forward(100) # 正しい
    # forward(100) # 間違い(NameErrorになる)
    
    もしfrom turtle import *を使っている場合、forward(100)のように直接関数名を呼び出せます。
    from turtle import *
    forward(100) # 正しい
    # turtle.forward(100) # 間違いではないが、from import * の意図と異なる
    

AttributeError: 'module' object has no attribute 'some_function'

エラーの原因
存在しない関数や属性をturtleモジュールから呼び出そうとした場合に発生します。これもスペルミスや、turtleモジュールにない機能を呼び出そうとしている可能性があります。

トラブルシューティング

  • バージョンの違い
    古いPythonのバージョンで書かれたコードを新しいバージョンで実行している場合、非推奨になった関数や変更されたAPIがあるかもしれません。その逆もまた然りです。
  • 関数名の確認
    使用している関数がturtleモジュールに実際に存在するか、ドキュメントで確認してください。例えば、turtle.move()という関数は存在せず、turtle.forward()が正しいです。

SyntaxError: invalid syntax

エラーの原因
これはPythonの一般的な構文エラーです。turtledemoのコードを直接編集したり、誤ってコピー&ペーストしたりした場合に発生しやすいです。

トラブルシューティング

  • turtledemoの直接実行方法の誤り
    python -m turtledemoのように、モジュールとして実行するべきところを、単にturtledemo.pyのように実行しようとした場合(Pythonのパスが通っていないなど)、このエラーが出る場合があります。正しい実行方法は通常、-mオプションを使用します。
  • キーワードの誤用
    for, if, whileなどのPythonの予約語を変数名として使っていないか確認してください。
  • インデント
    Pythonはインデントを構文の一部として使用します。スペースとタブが混在していないか、インデントのレベルが正しいかを確認してください。IndentationErrorとして明確に表示されることもありますが、SyntaxErrorの形で現れることもあります。
  • 括弧、引用符の閉じ忘れ
    丸括弧(), 角括弧[], 波括弧{}, シングルクォート'', ダブルクォート""などが正しく閉じられているか確認してください。

パフォーマンスの問題(描画が遅い、カクつく)

エラーの原因
非常に複雑な図形を描いたり、多くの描画コマンドを短時間で実行したりする場合、描画処理が追いつかずに遅くなったり、カクついたりすることがあります。

トラブルシューティング

  • turtle.speed() の調整
    タートルの移動速度を調整できます。speed(0)が最速(実際にはアニメーションを無効にする)。speed(1)が最も遅く、speed(10)が比較的速いです。
    turtle.speed(0) # 最速
    
  • turtle.tracer() の使用
    turtle.tracer(n, delay)関数は、描画の更新頻度を制御します。
    • turtle.tracer(0): 描画更新をオフにします。これにより、すべての描画コマンドが実行された後に一度に結果が表示され、非常に高速になります。
    • turtle.update(): turtle.tracer(0)を使った後、描画結果を表示するために明示的にturtle.update()を呼び出す必要があります。
    • turtle.tracer(1, 0)(デフォルト)は描画を各ステップで更新しますが、turtle.tracer(10, 0)のように値を大きくすると、10ステップごとに描画が更新されるようになり、速くなります。
    import turtle
    
    turtle.tracer(0) # 描画更新をオフに
    for i in range(360):
        turtle.forward(1)
        turtle.left(1)
    turtle.update() # すべての描画を一度に表示
    turtle.done()
    

環境に依存する問題 (例: 特定のOSでのみ発生)

エラーの原因
まれに、特定のオペレーティングシステムやPythonのバージョン、あるいはGUI環境(X serverなど)の設定に起因する問題が発生することがあります。

  • 別の環境での試行
    可能であれば、別のコンピュータや仮想環境でturtledemoを試してみて、問題が環境固有のものかどうかを特定します。
  • OS固有の依存関係
    特にLinuxでは、グラフィック関連のライブラリが不足している場合があります。上述のTkinterのインストールはその一例です。
  • Pythonのバージョンを確認
    使用しているPythonのバージョンがturtleモジュールと互換性があるか確認してください。公式ドキュメントで推奨されているバージョンを確認するのが良いでしょう。


turtleモジュールは、"タートル"と呼ばれる仮想のペンを使って図形を描くためのものです。基本的な動きといくつかの応用例を見ていきましょう。

基本的な動き:四角形を描く

最も基本的な描画は、タートルを前進させたり、方向転換させたりすることです。

import turtle # turtleモジュールをインポート

# スクリーンとタートルオブジェクトを作成
screen = turtle.Screen() # 描画するウィンドウ(スクリーン)を作成
t = turtle.Turtle()     # タートル(ペン)を作成

# 四角形を描く
for _ in range(4): # 4回繰り返す
    t.forward(100) # 100ピクセル前進
    t.right(90)    # 右に90度方向転換

# 描画が終わったら、ウィンドウを閉じずに待機
# t.done() は turtle.done() と同じ(from turtle import * をしていない場合)
screen.mainloop() # または turtle.done()

解説

  • screen.mainloop(): この行がないと、描画が完了した瞬間にウィンドウが閉じてしまいます。この行があることで、ユーザーがウィンドウを閉じるまでプログラムが待機します。
  • for _ in range(4): これにより、前進と右回転が4回繰り返され、正方形が描かれます。
  • t.right(90): タートルが右に90度回転します。
  • t.forward(100): タートルが向いている方向に100ピクセル進みます。
  • turtle.Turtle(): 実際に描画を行う「タートル」を作成します。このタートルが仮想のペンです。
  • turtle.Screen(): 描画が行われるグラフィックウィンドウを作成します。
  • import turtle: turtleモジュールをプログラムに読み込みます。

色とペンの制御:星を描く

色を変えたり、ペンを上げ下げしたりすることで、より複雑な図形を描くことができます。

import turtle

screen = turtle.Screen()
t = turtle.Turtle()

t.speed(1) # 描画速度を設定 (1-10, 0=最速)

# ペンの設定
t.pensize(3) # ペンの太さを3ピクセルに設定
t.pencolor("blue") # ペンの色を青に設定
t.fillcolor("yellow") # 塗りつぶしの色を黄色に設定

t.begin_fill() # 塗りつぶしの開始

# 星を描く(一般的な五芒星)
for _ in range(5):
    t.forward(150) # 150ピクセル前進
    t.right(144)   # 右に144度回転(360 / 5 * 2 = 144度)

t.end_fill() # 塗りつぶしの終了

# ペンを上げて、別の場所へ移動(線を描かずに移動)
t.penup() # ペンを上げる(これ以降は線を引かない)
t.goto(-100, 150) # (x, y)座標に移動
t.pendown() # ペンを下げる(これ以降は線を引く)

t.pencolor("red")
t.circle(50) # 半径50の円を描く

screen.mainloop()

解説

  • t.goto(x, y): 現在のタートルの位置に関係なく、指定された(x, y)座標へ移動します。
  • t.penup() / t.pendown(): penup()でペンを地面から上げると、その後forward()などで移動しても線が描画されません。pendown()でペンを下ろすと、再び線が描画されるようになります。
  • t.begin_fill() / t.end_fill(): これらの間に描かれた閉じられた図形がfillcolorで設定された色で塗りつぶされます。
  • t.fillcolor("yellow"): begin_fill()end_fill()で囲まれた領域の塗りつぶし色を設定します。
  • t.pencolor("blue"): 線の色を設定します。色の名前("red", "green", "blue"など)やHEXコード("#RRGGBB")を使えます。
  • t.pensize(3): 描画される線の太さを設定します。
  • t.speed(1): タートルの描画速度を制御します。0が最速で、アニメーションを省略します。1が最も遅く、10が速いです。

関数とランダム性:ランダムな点を描く

関数を使ってコードを整理したり、randomモジュールを使って描画にランダム性を加えたりすることができます。

import turtle
import random # ランダムな値を使うためにインポート

screen = turtle.Screen()
screen.setup(width=600, height=600) # スクリーンサイズを設定
screen.bgcolor("black") # 背景色を黒に設定

t = turtle.Turtle()
t.speed(0) # 最速で描画(アニメーションなし)
t.hideturtle() # タートル(矢印)を非表示にする

# ランダムな色の点を描画する関数
def draw_random_dot():
    x = random.randint(-280, 280) # X座標をランダムに生成
    y = random.randint(-280, 280) # Y座標をランダムに生成
    size = random.randint(5, 20)  # 点のサイズをランダムに生成

    # ランダムな色を生成
    r = random.random() # 0.0から1.0までの浮動小数点数
    g = random.random()
    b = random.random()
    t.pencolor(r, g, b) # RGB値で色を設定

    t.penup()
    t.goto(x, y)
    t.pendown()

    t.dot(size) # 指定されたサイズの点を描画

# 100個のランダムな点を描画
for _ in range(100):
    draw_random_dot()

screen.mainloop()

解説

  • t.dot(size): 現在のタートルの位置に、指定されたサイズの点を描画します。
  • random.random(): 0.0から1.0までのランダムな浮動小数点数を生成します。t.pencolor(r, g, b)のように、RGB値を0.0から1.0の範囲で指定できます。
  • random.randint(a, b): aからbまでのランダムな整数を生成します。
  • t.hideturtle(): タートル(通常は小さな矢印)を画面から非表示にします。複雑な描画では邪魔になることがあります。
  • screen.bgcolor("black"): スクリーン(背景)の色を設定します。
  • screen.setup(width, height): 描画ウィンドウのサイズを設定します。

イベント駆動型プログラミング:キー入力でタートルを動かす

turtledemoの中には、ユーザーのインタラクション(キーボード入力など)に反応するデモもあります。

import turtle

screen = turtle.Screen()
screen.setup(width=500, height=500)
screen.title("キーでタートルを動かす") # ウィンドウのタイトルを設定

t = turtle.Turtle()
t.shape("turtle") # タートルの形を"turtle"にする(デフォルトは"classic")
t.color("green")
t.speed(3)
t.pensize(2)

# 前進させる関数
def move_forward():
    t.forward(10)

# 後退させる関数
def move_backward():
    t.backward(10)

# 左に回転させる関数
def turn_left():
    t.left(30) # 30度左に回転

# 右に回転させる関数
def turn_right():
    t.right(30) # 30度右に回転

# キーイベントの設定
screen.listen() # キーボード入力をリッスンする状態にする
screen.onkey(move_forward, "Up")      # 上矢印キーが押されたらmove_forwardを実行
screen.onkey(move_backward, "Down")    # 下矢印キーが押されたらmove_backwardを実行
screen.onkey(turn_left, "Left")       # 左矢印キーが押されたらturn_leftを実行
screen.onkey(turn_right, "Right")     # 右矢印キーが押されたらturn_rightを実行

# 他にも 'a', 'b', 'space' などのキー名も使えます
# screen.onkey(t.clear, "c") # 'c'キーで描画をクリア

screen.mainloop()
  • screen.onkey(function, key): 指定されたkeyが押されたときに、functionを実行するように設定します。functionには引数がない関数を指定します。
  • screen.listen(): スクリーンがキーボードからの入力を待ち受けるように設定します。
  • t.shape("turtle"): タートルの表示形状を変更します。"arrow" (デフォルト), "turtle", "circle", "square", "triangle", "classic"などがあります。


turtleモジュールは初心者向けで、Logo言語のようなシンプルなコマンドで描画を楽しめますが、より高度なグラフィック処理、インタラクティブなアプリケーション、本格的なゲーム開発には、通常、より強力なライブラリやフレームワークが選ばれます。

Tkinter (標準ライブラリ)

  • コード例 (Tkinterで円を描く):
    import tkinter as tk
    
    def draw_circle():
        canvas.create_oval(50, 50, 150, 150, outline="blue", width=2, fill="lightblue")
    
    root = tk.Tk()
    root.title("Tkinter Demo")
    
    canvas = tk.Canvas(root, width=200, height=200, bg="white")
    canvas.pack()
    
    draw_button = tk.Button(root, text="円を描く", command=draw_circle)
    draw_button.pack()
    
    root.mainloop()
    
  • 用途: シンプルなユーティリティツール、学習用GUI。
  • 欠点:
    • モダンなルック&フィールではない。
    • 大規模な複雑なアプリケーションには向かない場合がある。
    • ゲーム開発には向いていない。
  • 利点:
    • Pythonに標準でバンドルされており、追加インストール不要。
    • シンプルなGUIアプリケーションを素早く作成できる。
    • クロスプラットフォーム(Windows, macOS, Linux)。
  • turtleとの関連性: turtleが描画に特化しているのに対し、Tkinterは一般的なデスクトップアプリケーションの構築に向いています。TkinterのCanvasウィジェットは、turtleのような2Dグラフィック描画機能を提供します。

Pygame (ゲーム開発向け)

  • コード例 (Pygameで円を動かす):
    import pygame
    
    pygame.init()
    
    screen_width = 600
    screen_height = 400
    screen = pygame.display.set_mode((screen_width, screen_height))
    pygame.display.set_caption("Pygame Demo")
    
    # 色の定義
    white = (255, 255, 255)
    red = (255, 0, 0)
    
    # 円の初期位置と速度
    circle_x = screen_width // 2
    circle_y = screen_height // 2
    circle_radius = 20
    circle_speed = 5
    
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    circle_x -= circle_speed
                if event.key == pygame.K_RIGHT:
                    circle_x += circle_speed
                if event.key == pygame.K_UP:
                    circle_y -= circle_speed
                if event.key == pygame.K_DOWN:
                    circle_y += circle_speed
    
        # 画面を白で塗りつぶす
        screen.fill(white)
    
        # 円を描画
        pygame.draw.circle(screen, red, (circle_x, circle_y), circle_radius)
    
        # 画面を更新
        pygame.display.flip()
    
    pygame.quit()
    
  • 用途: レトロゲーム、パズルゲーム、プラットフォームゲームなど、2Dゲーム全般。
  • 欠点:
    • 3Dゲームには不向き。
    • GUIアプリケーション開発には適していない。
  • 利点:
    • 2Dゲーム開発に最適化されている。
    • 豊富な機能と活発なコミュニティ。
    • 比較的学習しやすい。
    • クロスプラットフォーム。
  • turtleとの違い: turtleが「ペンで描く」ことに重点を置いているのに対し、Pygameは「スプライト」(画像やアニメーション)や「サーフェス」(描画領域)を直接操作し、フレームごとに画面を更新することでゲームロジックを実装します。より高速で複雑なアニメーションが可能です。

Kivy (マルチタッチ対応GUI/ゲーム)

  • コード例 (Kivyでボタンとラベル):
    from kivy.app import App
    from kivy.uix.button import Button
    from kivy.uix.label import Label
    from kivy.uix.boxlayout import BoxLayout
    
    class MyKivyApp(App):
        def build(self):
            layout = BoxLayout(orientation='vertical')
    
            label = Label(text="Kivyへようこそ!")
            layout.add_widget(label)
    
            button = Button(text="クリックしてね!", size_hint=(1, 0.2))
            button.bind(on_press=self.on_button_press)
            layout.add_widget(button)
    
            return layout
    
        def on_button_press(self, instance):
            print("ボタンがクリックされました!")
            # ラベルのテキストを変更することも可能
            # self.root.children[1].text = "クリックされたよ!" # レイアウトの構造による
    
    if __name__ == '__main__':
        MyKivyApp().run()
    
  • 用途: タッチベースのアプリケーション、モバイルゲーム、情報キオスク。
  • 欠点:
    • 学習曲線がやや急。
    • デスクトップアプリケーションとしてはネイティブ感が薄い場合がある。
  • 利点:
    • 優れたマルチタッチサポート。
    • クロスプラットフォーム(Android, iOS, Windows, macOS, Linux, Raspberry Pi)。
    • OpenGL ES 2を利用した高速なグラフィック描画。
    • 宣言的なUI記述言語(KV Language)がある。

PyOpenGL / moderngl (3Dグラフィック)

  • 用途: 3Dゲーム、科学的可視化、シミュレーション、リアルタイムレンダリング。
  • 欠点:
    • 非常に学習が難しい(グラフィックパイプラインの知識が必要)。
    • コード量が多くなりがち。
  • 利点:
    • 高性能な3Dグラフィックが可能。
    • グラフィックカードのハードウェアアクセラレーションを利用。
    • 高度な視覚効果を実装できる。
  • turtleとの違い: turtleが2Dの簡易描画であるのに対し、OpenGLは頂点、テクスチャ、シェーダーなどを直接操作して複雑な3Dシーンを構築します。学習コストは高いですが、パフォーマンスと自由度が非常に高いです。

Matplotlib (データ可視化)

  • コード例 (Matplotlibで簡単なグラフ):
    import matplotlib.pyplot as plt
    import numpy as np
    
    # データの生成
    x = np.linspace(0, 10, 100) # 0から10までの100個の点
    y = np.sin(x)               # sin関数
    
    # プロット
    plt.plot(x, y)
    plt.title("サイン波")
    plt.xlabel("X軸")
    plt.ylabel("Y軸")
    plt.grid(True) # グリッドを表示
    plt.show()
    
  • 用途: データ分析、統計グラフ、論文やレポートの図。
  • 欠点:
    • 一般的なグラフィックアプリケーションやゲーム開発には向かない。
    • インタラクティブ性は限定的。
  • 利点:
    • データサイエンス分野で標準的。
    • 高品質なグラフとプロットを作成できる。
    • 非常に柔軟でカスタマイズ性が高い。
  • turtleとの違い: turtleが「自由な絵を描く」ことを目的としているのに対し、Matplotlibは「データに基づいて図形を描く」ことを目的としています。データのパターンや傾向を視覚的に表現するのに特化しています。

PyQT / PyQt5 / PySide2 (Qtフレームワークのバインディング)

  • 用途: 複雑なデスクトップアプリケーション、IDE、ビジネスアプリケーション。
  • 欠点:
    • 商用利用の場合、ライセンスに注意が必要な場合がある(PyQtはGPL、PySideはLGPL)。
    • 学習曲線は比較的高め。
  • 利点:
    • プロフェッショナルな見た目のGUIアプリケーションを開発できる。
    • 豊富なウィジェットと機能(グラフィックビュー、データベース連携など)。
    • クロスプラットフォーム。
    • 大規模なアプリケーション開発に適している。
  • プロフェッショナルなデスクトップアプリを作りたい: PyQt / PySide
  • データをグラフで可視化したい: Matplotlib
  • 高度な3Dグラフィックを扱いたい: PyOpenGL / moderngl
  • タッチ対応のモダンなUIやモバイルアプリを作りたい: Kivy
  • 2Dゲームを作りたい: Pygame (最も一般的)
  • シンプルなデスクトップアプリやUIを試したい: Tkinter
  • 初心者で簡単な絵を描きたい: turtle (これを見ていますね!)