Turtle Graphicsの色が変わらない?colormode()のエラーと解決策

2025-06-06

turtle.colormode() とは何か

turtle.colormode()は、Pythonのturtleグラフィックスライブラリにおいて、色の指定方法を設定するための関数です。この関数を使うことで、色を表現する際の数値の範囲を255段階(0-255)にするか、浮動小数点数(0.0-1.0)にするかを切り替えることができます。

主な使い方とモード

turtle.colormode()には、主に以下の2つのモードがあります。

    • このモードを設定すると、色の各成分(赤、緑、青)を0から255までの整数で指定するようになります。これは、一般的なデジタル画像やウェブカラーでよく使われるRGB値の形式に似ています。
    • 例: turtle.pencolor(255, 0, 0) は純粋な赤を示します。
  1. turtle.colormode(1.0) (または turtle.colormode(255))

    • このモードを設定すると、色の各成分を0から1.0までの浮動小数点数で指定するようになります。これは、OpenGLなどのグラフィックライブラリでよく用いられる形式です。
    • turtleモジュールのデフォルトのモードは1.0です。
    • 例: turtle.pencolor(1.0, 0.0, 0.0) は純粋な赤を示します。

なぜこれが必要なのか?

colormode()を設定する理由は、プログラマーが慣れている色の指定方法に合わせて柔軟に対応するためです。

  • もし数学的な計算やグラフィック理論に基づいて色を扱いたい場合、colormode(1.0)の方が適しているかもしれません。
  • もしPhotoshopやGIMPなどの画像編集ソフトウェアでRGB値を扱っている場合、colormode(255)に設定する方が直感的で分かりやすいでしょう。

以下に、それぞれのモードでの使用例を示します。

import turtle

# デフォルトは colormode(1.0) ですが、明示的に設定してみます
turtle.colormode(1.0)
screen = turtle.Screen()
screen.setup(width=600, height=400)

t = turtle.Turtle()
t.speed(0) # 最速

# モード 1.0 で色を指定
t.penup()
t.goto(-100, 50)
t.pendown()
t.pencolor(1.0, 0.0, 0.0) # 赤
t.forward(50)
t.write("Red (1.0)", font=("Arial", 12, "normal"))

t.penup()
t.goto(-100, 0)
t.pendown()
t.pencolor(0.0, 1.0, 0.0) # 緑
t.forward(50)
t.write("Green (1.0)", font=("Arial", 12, "normal"))

# colormode を 255 に変更
turtle.colormode(255)

t.penup()
t.goto(100, 50)
t.pendown()
t.pencolor(255, 0, 0) # 赤
t.forward(50)
t.write("Red (255)", font=("Arial", 12, "normal"))

t.penup()
t.goto(100, 0)
t.pendown()
t.pencolor(0, 255, 0) # 緑
t.forward(50)
t.write("Green (255)", font=("Arial", 12, "normal"))

screen.mainloop()


turtle.colormode()に関するよくあるエラーとトラブルシューティング

turtle.colormode()は色の指定方法(0.0-1.0 または 0-255)を切り替える重要な関数ですが、この設定と実際の色の値が一致しないとエラーが発生したり、意図しない色が表示されたりします。

エラー:colormodeと色の値の不一致

これが最も頻繁に発生するエラーです。colormode()で設定した数値の範囲と、pencolor()fillcolor()などの色指定関数に渡す値の形式が一致しない場合に起こります。

  • 解決策
    turtle.colormode()で設定したモードに合わせて、色の値を正しく指定してください。

    • turtle.colormode(255) の場合
      import turtle
      screen = turtle.Screen()
      turtle.colormode(255) # 0-255モードに設定
      t = turtle.Turtle()
      t.pencolor(255, 0, 0)   # 赤 (R=255, G=0, B=0)
      t.forward(100)
      screen.mainloop()
      
    • turtle.colormode(1.0) の場合 (デフォルト)
      import turtle
      screen = turtle.Screen()
      # turtle.colormode(1.0) # デフォルトなので省略可ですが、明示してもOK
      t = turtle.Turtle()
      t.pencolor(1.0, 0.0, 0.0) # 赤 (R=1.0, G=0.0, B=0.0)
      t.forward(100)
      screen.mainloop()
      
  • エラーメッセージ例

    • turtle.TurtleGraphicsError: bad color sequence: (0.5, 0.0, 0.0)
    • または、特にcolormode(1.0)の際に255を超える整数を指定した場合、エラーにはならずとも色が白(1.0, 1.0, 1.0)にクリップされるなど、意図しない結果になることがあります。これは、128などの値が1.0に丸められるためです。
    • turtle.colormode(255)を設定しているのに、色を浮動小数点数(例: (0.5, 0.0, 0.0))で指定する。
    • turtle.colormode(1.0)(またはデフォルトのまま)なのに、色を0-255の整数(例: (255, 0, 0))で指定する。

エラー:colormode()の引数エラー

turtle.colormode()関数に、1.0または255以外の不正な引数を渡した場合に発生します。

  • 解決策
    turtle.colormode()に渡せる引数は、0(浮動小数点数)または255(整数)のいずれかのみです。

    import turtle
    # 正しい例:
    turtle.colormode(255) # OK
    # turtle.colormode(1.0) # OK
    
  • エラーメッセージ例

    • ValueError: mode must be 1.0 or 255
  • 発生する状況

    • turtle.colormode(100)
    • turtle.colormode("my_mode")

エラー:colormode()設定のタイミング

turtle.colormode()を呼び出す前に、デフォルトのモードと異なる色の指定をしてしまうと、エラーが発生します。

  • 解決策
    turtle.colormode()の設定は、色の指定を行うコードの前に、プログラムの初期設定部分で呼び出すようにしてください。

    import turtle
    screen = turtle.Screen()
    
    # 必ず色の指定より前に colormode を設定する
    turtle.colormode(255)
    
    t = turtle.Turtle()
    t.pencolor(255, 0, 0) # これでエラーは発生しない
    t.forward(100)
    screen.mainloop()
    
  • エラーメッセージ例

    • turtle.TurtleGraphicsError: bad color sequence: (255, 0, 0)
  • 発生する状況
    turtleのデフォルトのcolormode1.0です。そのため、turtle.colormode(255)を設定する前に、pencolor(255, 0, 0)のように255形式で色を指定すると、エラーになります。

    import turtle
    t = turtle.Turtle()
    # ここではまだ colormode(1.0) が有効
    t.pencolor(255, 0, 0) # エラーが発生! (colormode(1.0)なのに255形式で指定)
    turtle.colormode(255) # colormodeの変更が遅い
    
  • コードの簡素化
    複雑なコードでエラーが発生した場合は、colormodeと色指定の部分だけを抜き出して、簡単なコードでテストしてみると原因が特定しやすくなります。
  • 現在のcolormodeを確認する
    デバッグ中に現在のcolormodeが何になっているか確認したい場合は、print(turtle.colormode())を実行すると表示されます。
    import turtle
    print(turtle.colormode()) # デフォルトなら 1.0 と表示される
    turtle.colormode(255)
    print(turtle.colormode()) # 255 と表示される
    
  • エラーメッセージをよく読む
    Pythonのエラーメッセージは、どこで何が間違っているかを示す重要な手がかりです。特にTypeErrorValueErrorTurtleGraphicsErrorが出て、bad color sequenceのような記述があれば、colormodeと色の値の不一致を疑ってください。


turtle.colormode()は、色の指定方法を「0.0から1.0までの浮動小数点数」で表すか、「0から255までの整数」で表すかを切り替えるために使われます。これにより、色の扱いに柔軟性を持たせることができます。

例1: デフォルトモード (colormode(1.0)) での色指定

turtleモジュールのデフォルトのcolormode1.0です。このモードでは、RGBの各成分(赤、緑、青)を0.0から1.0の間の浮動小数点数で指定します。

import turtle

# 1. スクリーンとタートルを準備
screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.title("Colormode 1.0 Example")

t = turtle.Turtle()
t.speed(0) # 描画速度を最速に設定

# 2. colormodeを1.0に設定(デフォルトなので省略可ですが、明示的に記述)
turtle.colormode(1.0)
print(f"現在のカラーモード: {turtle.colormode()}")

# 3. 色を0.0-1.0の浮動小数点数で指定して描画
# 純粋な赤
t.penup()
t.goto(-200, 50)
t.pendown()
t.pencolor(1.0, 0.0, 0.0) # RGB (赤, 緑, 青)
t.pensize(5)
t.forward(100)
t.write("赤 (1.0)", font=("Arial", 12, "normal"))

# 暗い緑
t.penup()
t.goto(-200, 0)
t.pendown()
t.pencolor(0.0, 0.5, 0.0) # 中くらいの緑
t.pensize(5)
t.forward(100)
t.write("暗い緑 (1.0)", font=("Arial", 12, "normal"))

# 半透明の青 (turtleはalphaチャンネルを直接サポートしませんが、値の範囲を示す例として)
t.penup()
t.goto(-200, -50)
t.pendown()
t.pencolor(0.0, 0.0, 0.7) # 少し薄い青
t.pensize(5)
t.forward(100)
t.write("青 (1.0)", font=("Arial", 12, "normal"))

# 4. ウィンドウを閉じないようにする
screen.mainloop()

例2: 255モード (colormode(255)) での色指定

このモードでは、RGBの各成分を0から255までの整数で指定します。これは、Webカラーやグラフィックソフトウェアでよく使われる形式です。

import turtle

# 1. スクリーンとタートルを準備
screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.title("Colormode 255 Example")

t = turtle.Turtle()
t.speed(0) # 描画速度を最速に設定

# 2. colormodeを255に設定
turtle.colormode(255)
print(f"現在のカラーモード: {turtle.colormode()}")

# 3. 色を0-255の整数で指定して描画
# 純粋な青
t.penup()
t.goto(-200, 50)
t.pendown()
t.pencolor(0, 0, 255) # RGB (赤, 緑, 青)
t.pensize(5)
t.forward(100)
t.write("青 (255)", font=("Arial", 12, "normal"))

# オレンジ
t.penup()
t.goto(-200, 0)
t.pendown()
t.pencolor(255, 165, 0) # オレンジ
t.pensize(5)
t.forward(100)
t.write("オレンジ (255)", font=("Arial", 12, "normal"))

# 濃い紫
t.penup()
t.goto(-200, -50)
t.pendown()
t.pencolor(128, 0, 128) # 濃い紫
t.pensize(5)
t.forward(100)
t.write("濃い紫 (255)", font=("Arial", 12, "normal"))

# 4. ウィンドウを閉じないようにする
screen.mainloop()

例3: プログラム内でモードを切り替える

プログラムの実行中にcolormodeを切り替えることも可能です。ただし、色の指定を行う前に、必ずそのモードを設定しておく必要があります。

import turtle

screen = turtle.Screen()
screen.setup(width=700, height=500)
screen.title("Colormode Switching Example")

t = turtle.Turtle()
t.speed(0)

# ----- まずは colormode(1.0) で描画 -----
turtle.colormode(1.0)
print(f"描画開始時のカラーモード: {turtle.colormode()}")

t.penup()
t.goto(-250, 100)
t.pendown()
t.pencolor(0.8, 0.2, 0.2) # 明るい赤
t.pensize(5)
t.forward(100)
t.write("明るい赤 (1.0)", font=("Arial", 12, "normal"))

# 図形を描いてみる
t.fillcolor(0.2, 0.8, 0.2) # 緑
t.begin_fill()
for _ in range(4):
    t.forward(50)
    t.left(90)
t.end_fill()

# ----- colormodeを255に切り替える -----
turtle.colormode(255)
print(f"モード切り替え後のカラーモード: {turtle.colormode()}")

t.penup()
t.goto(50, 100)
t.pendown()
t.pencolor(0, 0, 200) # 濃い青
t.pensize(5)
t.forward(100)
t.write("濃い青 (255)", font=("Arial", 12, "normal"))

# 別の図形を描いてみる
t.fillcolor(255, 255, 0) # 黄色
t.begin_fill()
for _ in range(3):
    t.forward(60)
    t.left(120)
t.end_fill()

# --- 注意: ここでcolormodeを切り替えずに1.0形式で色を指定するとエラー ---
# t.pencolor(0.5, 0.5, 0.5) # colormode(255)なのでエラーになる!
# Traceback (most recent call last):
#   ...
# turtle.TurtleGraphicsError: bad color sequence: (0.5, 0.5, 0.5)

screen.mainloop()


turtle.colormode()は、RGB値をタプル(例:(R, G, B))で指定する際に、その数値が0-255の範囲か0.0-1.0の範囲かをturtleに伝える役割があります。しかし、色の指定方法には他にも種類があり、これらはcolormode()の設定に直接影響されません。

色の名前(文字列)で指定する

最もシンプルで、colormode()の設定に関係なく使える方法です。turtleモジュールには、あらかじめ定義された多くの色の名前が用意されています。

  • 使用例
    import turtle
    
    screen = turtle.Screen()
    t = turtle.Turtle()
    t.speed(1)
    
    # colormodeの設定とは無関係に動作します
    turtle.colormode(255) # 例として255モードに設定しておく
    
    t.pencolor("red")      # 赤色
    t.forward(50)
    
    t.pencolor("blue")     # 青色
    t.forward(50)
    
    t.pencolor("green")    # 緑色
    t.forward(50)
    
    t.pencolor("hotpink")  # ホットピンク
    t.forward(50)
    
    t.pencolor("chocolate") # チョコレート色
    t.forward(50)
    
    screen.mainloop()
    
  • 特徴
    • 非常に直感的で読みやすい。
    • colormode()の影響を全く受けない。
    • 使える色の種類は、定義済みの名前のみに限られる。

16進数カラーコード(文字列)で指定する

ウェブデザインなどでよく使われる#RRGGBB形式の16進数カラーコード(文字列)で色を指定することもできます。この方法もcolormode()の設定に依存しません。

  • 使用例
    import turtle
    
    screen = turtle.Screen()
    t = turtle.Turtle()
    t.speed(1)
    
    # colormodeの設定とは無関係に動作します
    turtle.colormode(1.0) # 例として1.0モードに設定しておく
    
    t.pencolor("#FF0000") # 赤
    t.forward(50)
    
    t.pencolor("#00FF00") # 緑
    t.forward(50)
    
    t.pencolor("#0000FF") # 青
    t.forward(50)
    
    t.pencolor("#FFD700") # ゴールド
    t.forward(50)
    
    t.pencolor("#8A2BE2") # ブルーバイオレット
    t.forward(50)
    
    screen.mainloop()
    
  • 特徴
    • 約1670万色(フルカラー)を指定できるため、非常に多くの色を表現できる。
    • colormode()の影響を受けない。
    • ウェブカラーや他のグラフィックツールと互換性が高い。
    • 16進数表現に慣れる必要はある。

colormode()の現在の値を取得して動的に処理する(汎用的な色の指定関数)

これは直接的な「代替手段」というよりは、どのようなcolormode()が設定されていても、常に意図した色のRGB値を渡せるようにするためのプログラミング手法です。例えば、常に0-255の範囲で色を管理したいが、colormode()が1.0に設定されている可能性も考慮したい場合に有効です。

  • 使用例
    import turtle
    
    screen = turtle.Screen()
    screen.setup(width=600, height=400)
    t = turtle.Turtle()
    t.speed(0)
    
    # どんなcolormodeでも機能する色の設定関数を定義
    def set_universal_color(turtle_obj, r_255, g_255, b_255):
        """
        現在のcolormodeに応じて、0-255のRGB値を適切に変換して色を設定します。
        引数:
            turtle_obj: 色を設定するタートルオブジェクト
            r_255, g_255, b_255: 0-255の範囲で指定されたRGB値
        """
        current_mode = turtle.colormode()
        if current_mode == 255:
            # colormodeが255なら、そのまま0-255の値を渡す
            turtle_obj.pencolor(r_255, g_255, b_255)
        elif current_mode == 1.0:
            # colormodeが1.0なら、0-1.0に変換して渡す
            turtle_obj.pencolor(r_255 / 255.0, g_255 / 255.0, b_255 / 255.0)
        else:
            # 想定外のcolormodeがあればエラーを出すか、デフォルト処理を行う
            print(f"警告: 未対応のcolormodeが検出されました: {current_mode}")
            # fall-back to 1.0 mode if unexpected
            turtle_obj.pencolor(r_255 / 255.0, g_255 / 255.0, b_255 / 255.0)
    
    
    # ----- colormode(1.0) の場合で試す -----
    turtle.colormode(1.0)
    print(f"現在のカラーモード: {turtle.colormode()}")
    
    t.penup()
    t.goto(-100, 50)
    t.pendown()
    set_universal_color(t, 255, 0, 0) # 255形式で指定するが、内部で1.0に変換される
    t.forward(100)
    t.write("赤 (Universal)", font=("Arial", 12, "normal"))
    
    # ----- colormode(255) の場合で試す -----
    turtle.colormode(255)
    print(f"現在のカラーモード: {turtle.colormode()}")
    
    t.penup()
    t.goto(-100, 0)
    t.pendown()
    set_universal_color(t, 0, 128, 0) # 255形式で指定し、そのまま使用される
    t.forward(100)
    t.write("濃い緑 (Universal)", font=("Arial", 12, "normal"))
    
    screen.mainloop()
    
  • 特徴
    • プログラムがどんなcolormode()の設定でも、期待通りに色を扱えるようになる。
    • コードがやや複雑になるが、柔軟性が高まる。
  • プログラム内でRGBタプルを使い分けたいが、colormode()に依存しない柔軟なコードを書きたい場合
    colormode()の現在の値を取得し、それに基づいてRGB値を変換する独自のヘルパー関数を定義するのが良いでしょう。
  • 豊富な色を使いたい、ウェブデザインなどと互換性を保ちたい場合
    16進数カラーコード("#FF0000"など)が強力な選択肢です。
  • 簡単さ優先、色の種類が限定的でよい場合
    色の名前("red", "blue"など)を使うのが最も手軽です。