ChatGPTで図を生成する方法 : コードを生成する

別のブログの記事で色空間のことを書くのに、Adobe RGBやsRGBといった色空間を説明するための図が必要になりました。必要なのはCIE 1931 カラースペクトルを背景に、各色空間がカラースペクトル上でどの範囲をカバーするかを示す図です。

手書きするのは正確性に欠けるなと思い、それならば、ChatGPTを使って描くことができないかと考えました。

この記事はその試行錯誤とその結果を共有するための記事です。

目次

ChatGPTは直接図を書くことができるのだろうか?

ChatGPTに図を描く能力はあるのかをまずは試してみました。ChatGPTに次のプロンプトを入力しました。

人間が視覚できる可視光(色)の中でsRGBの色域はどの範囲かを示すチャートを作成してください。

ChatGPTは次のように回答しました。

私はチャートや画像を直接作成することはできませんが、説明を提供して、あなたがイメージを描くのを助けることができます。

可視光スペクトルは波長が約380nmから780nmの範囲で、人間の目によって認識される色を含んでいます。sRGB色域は、可視光スペクトル内のある特定の範囲をカバーしており、ほとんどの標準的なディスプレイやデバイスで再現できるように設計されています。

sRGBの色域をチャートで表示するには、CIE 1931色空間図 (xy色空間) を使用します。CIE 1931色空間図は、x軸とy軸を持つ二次元のグラフで、可視光スペクトルのすべての色をカバーしています。この図では、馬蹄型の形をした範囲が、人間が認識できるすべての色を表しています。

sRGBの色域は、この馬蹄型の範囲内の三角形で表されます。sRGBの三角形の頂点は、赤、緑、青の基本色の座標を示しており、それぞれ次のようになっています:

赤: x = 0.6400, y = 0.3300
緑: x = 0.3000, y = 0.6000
青: x = 0.1500, y = 0.0600
これらの座標をCIE 1931色空間図にプロットし、三角形を描くことで、sRGB色域を視覚化できます。この三角形の内部にある色は、sRGB色域で表現できる色です。

どうやらChatGPTには図を描く、もしくは生成するという能力は無いようです。しかし、DALL-EやStableDiffusionといった画像生成系AIは今回の用途には使えないだろうということも感覚的に分かります。

SVGを生成する

ChatGPTはコードを生成することができます。それならば、コードで図を表現できるデータならば生成することが可能なはずです。まずは、SVGを試してみます。プロンプトは次の通りです。

直接図を作ることはできないのですね。では代わりにSVGなどで表現することはできますか?

すると、予想した通りSVGのコードを生成することができました。

私はSVGファイルを直接生成することはできませんが、sRGBの色域を表現するためのSVG形状を記述する方法を示すことができます。これにより、あなた自身でSVGファイルを作成できます。

以下のサンプルコードは、sRGB色域を描画するSVGの例です。これをSVGファイルまたはHTMLファイル内に挿入することができます。
<svg width="500" height="500" xmlns="http://www.w3.org/2000/svg">
  <rect width="100%" height="100%" fill="white" />
  <polygon points="320,165 150,300 60,60" stroke="black" fill="none" stroke-width="2" />
  <circle cx="320" cy="165" r="4" stroke="red" fill="red" />
  <circle cx="150" cy="300" r="4" stroke="green" fill="green" />
  <circle cx="60" cy="60" r="4" stroke="blue" fill="blue" />
  <text x="320" y="165" font-family="Arial" font-size="14" fill="black" dy="1.5em" dx="-1em">Red</text>
  <text x="150" y="300" font-family="Arial" font-size="14" fill="black" dy="1.5em" dx="-1em">Green</text>
  <text x="60" y="60" font-family="Arial" font-size="14" fill="black" dy="1.5em" dx="-1em">Blue</text>
</svg>
このコードは、500x500ピクセルのSVGキャンバスを作成し、白い背景を持つ長方形を描画します。その後、sRGBの色域を表現するポリゴンを描画し、赤、緑、青の基本色を表す円を追加します。最後に、各基本色のラベルを描画します。

このコードは、実際のCIE 1931色空間図とは異なる座標系を使用しています。実際の座標を使用してSVGを作成するには、座標変換を適用し、適切な縮尺を使用する必要があります。しかし、この例はsRGB色域を視覚化するための基本的なアプローチを示しています。

生成されたコードの先頭に次の2行を追加して、sample.svgなどのファイル名で保存し、ビューアで開いてみると次のような図が表示されました。

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
sRGBの色域の描画

コードを生成するという方法でなら、ChatGPTを使って図を作ることができそうです。

Pythonのコードを生成する

もっと柔軟にコントロールできるようにするには、SVGを生成するよりも、Pythonのコードを生成して、手で修正するのが良さそうです。

CIE 1931 カラースペクトルを描くコードを作る

CIE 1931 カラースペクトルを描くコードを作ります。ChatGPTに次のプロンプトを入力しました。

CIE 1931 色空間を描くpythonのコードを作成してください。
各座標の色も着色してください。

すると次のような回答が表示されました。

以下は、CIE 1931 色空間図(xy色度図)を描画し、各座標の色も着色するPythonプログラムです。colour-scienceパッケージとmatplotlibを使用しています。まず、これらのライブラリをインストールしてください。
pip install colour-science matplotlib
次に、以下のコードを実行してください。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import colour

def draw_cie1931_chromaticity_diagram():
    # Draw horseshoe shape with spectral colors
    wavelengths = np.arange(380, 781, 5)
    xy_points = []
    for wl in wavelengths:
        xyz = colour.wavelength_to_XYZ(wl)
        x, y = colour.XYZ_to_xy(xyz)
        xy_points.append([x, y])

    # Create the meshgrid
    x_points = np.linspace(0, 0.8, 800)
    y_points = np.linspace(0, 0.9, 900)
    xx, yy = np.meshgrid(x_points, y_points)

    # Create the RGB image
    img = np.zeros((900, 800, 3))
    for i, y_val in enumerate(y_points):
        for j, x_val in enumerate(x_points):
            x, y = x_val, y_val
            z = 1.0 - x - y
            if x < 0 or y < 0 or z < 0:
                continue
            xyz = np.array([x, y, z]) * 100.0
            try:
                rgb = colour.XYZ_to_sRGB(xyz)
                if (rgb >= 0).all() and (rgb <= 1).all():
                    img[i, j] = rgb
            except:
                pass

    # Plot the image
    plt.imshow(img, extent=(0, 0.8, 0, 0.9), origin='lower')

    # Draw the outline of the horseshoe shape
    xy_points.append(xy_points[0])
    x, y = zip(*xy_points)
    plt.plot(x, y, color='black')

    # Set up the plot
    plt.xlim(0, 0.8)
    plt.ylim(0, 0.9)
    plt.xlabel("x")
    plt.ylabel("y")
    plt.title("CIE 1931 Chromaticity Diagram")
    plt.gca().set_aspect('equal', adjustable='box')

    plt.show()

draw_cie1931_chromaticity_diagram()

しかし、このコードは色々と問題がありました。まず第一に重いです。また、表示される画像は黒一色で要求した動作をしません。

そこで、次のようにプロンプトを入力しました。

このコードは実行すると非常に負荷がかかる上に、色も付かず、本来書かれるはずの線も消えてしまいました。

そして新しいコードが生成されましたが、まだ、重いので、再び上記の様な「重い」ということを入力しました。最終的に次のコードが作られました。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import colour
from colour.plotting import *  # Required for 'plot_chromaticity_diagram_CIE1931' function

colour.plotting.plot_chromaticity_diagram_CIE1931(standalone=True, title='CIE 1931 Chromaticity Diagram', spectral_locus_colours=True)

ずいぶんシンプルになりましたね。まだ、問題があります。plot_chromaticity_diagram_CIE1931は古いAPIのようです。さらにChatGPTに修正の指示を与えると、最終的に次のコードができました。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import colour
from colour.plotting import plot_chromaticity_diagram

# Plot the CIE 1931 chromaticity diagram
plot_chromaticity_diagram(illuminant='D65', observer='CIE 1931 2 Degree Standard Observer', diagram_opacity=0, diagram_clipping_path=None, standalone=False)

生成したコードを修正する

ChatGPTを使って作ったコードはまだ問題があります。ChatGPTにエラーメッセージを入力して修正させるということを繰り返しても解決できませんでした。生成されたコードの確認と検証は人間が行うべきであることが分かります。

from colour.plotting import plot_chromaticity_diagram

この行は中途半端なコードになっています。次のように.diagramsを追加します。

from colour.plotting.diagrams import plot_chromaticity_diagram

また、plot_chromaticity_diagram関数の引数は今回はstandalone=Trueだけで十分です。修正後のコードは次のようになります。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import colour
from colour.plotting.diagrams import plot_chromaticity_diagram

# Plot the CIE 1931 chromaticity diagram
plot_chromaticity_diagram(standalone=True)

このコードを実行すると次のように図が表示されます。

CIE 1931 カラースペクトル

sRGBの色域を描画するコードを生成する

次にこれを背景にして、sRGBの色域を描画するコードを追加したコードを生成します。次のようにプロンプトに入力します。

次のコードを使ってカラースペクトルを描き、その上にsRGBの色域を三角形で描くPythonのコードを作成してください。

```
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import colour
from colour.plotting.diagrams import plot_chromaticity_diagram

# Plot the CIE 1931 chromaticity diagram
plot_chromaticity_diagram(standalone=True)
```

次のコードが生成されます。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import colour
from colour.plotting.diagrams import plot_chromaticity_diagram

# Plot the CIE 1931 chromaticity diagram
plot_chromaticity_diagram(standalone=False)

# Define sRGB primaries and white point
sRGB_primaries = np.array([
    [0.6400, 0.3300],
    [0.3000, 0.6000],
    [0.1500, 0.0600]
])

D65_white_point = np.array([0.3127, 0.3290])

# Create a polygon with the sRGB primaries
sRGB_triangle = Polygon(sRGB_primaries, edgecolor='black', facecolor='none', linewidth=2)

# Get the current axis and add the sRGB triangle
ax = plt.gca()
ax.add_patch(sRGB_triangle)

# Plot the D65 white point
ax.plot(D65_white_point[0], D65_white_point[1], 'o', color='white', markersize=10, markeredgecolor='black')

# Display the plot
plt.show()

このコードは正しく動作します。実行すると次のようにsRGBの色域を示すトライアングルが追加されます。

CIE 1931 カラースペクトルとsRGB

Adobe RGB, Display P3, HDR10の描画を追加する

今回作りたい図の目的はsRGBだけではなく、いくつかの色域の比較です。そのため、次の色空間の色域の描画処理も追加する必要があります。

  • Adobe RGB
  • Display P3
  • HDR10

そこで、次のようにプロンプトに入力します。

このコードはCIEカラースペクトルとsRGBの色域を示す図を描画するPythonのコードです。
このコードを元にsRGBだけではなく、AdobeRGB, Display P3, HDR10の色域を描画するように変更してください。

これに対して、次のコードが生成されます。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import colour
from colour.plotting.diagrams import plot_chromaticity_diagram

# Plot the CIE 1931 chromaticity diagram
plot_chromaticity_diagram(standalone=False)

# Define color space primaries and white point
sRGB_primaries = np.array([
    [0.6400, 0.3300],
    [0.3000, 0.6000],
    [0.1500, 0.0600]
])

AdobeRGB_primaries = np.array([
    [0.6400, 0.3300],
    [0.2100, 0.7100],
    [0.1500, 0.0600]
])

Display_P3_primaries = np.array([
    [0.6800, 0.3200],
    [0.2650, 0.6900],
    [0.1500, 0.0600]
])

HDR10_primaries = np.array([
    [0.7080, 0.2920],
    [0.1700, 0.7970],
    [0.1310, 0.0460]
])

D65_white_point = np.array([0.3127, 0.3290])

# Create polygons with the color space primaries
sRGB_triangle = Polygon(sRGB_primaries, edgecolor='black', facecolor='none', linewidth=2, label='sRGB')
AdobeRGB_triangle = Polygon(AdobeRGB_primaries, edgecolor='red', facecolor='none', linewidth=2, label='AdobeRGB')
Display_P3_triangle = Polygon(Display_P3_primaries, edgecolor='blue', facecolor='none', linewidth=2, label='Display P3')
HDR10_triangle = Polygon(HDR10_primaries, edgecolor='green', facecolor='none', linewidth=2, label='HDR10')

# Get the current axis and add the color space triangles
ax = plt.gca()
ax.add_patch(sRGB_triangle)
ax.add_patch(AdobeRGB_triangle)
ax.add_patch(Display_P3_triangle)
ax.add_patch(HDR10_triangle)

# Plot the D65 white point
ax.plot(D65_white_point[0], D65_white_point[1], 'o', color='white', markersize=10, markeredgecolor='black')

# Add legend
plt.legend(loc='upper right')

# Display the plot
plt.show()

このコードを実行すると次のような図が表示されます。

CIE 1931 カラースペクトルとsRGB, Adobe RGB, Display P3, HDR10

これで目的の図を描画するコードが完成しました。

まとめ

ChatGPTは図を直接生成することはできませんが、図を生成するコードを生成できます。これを利用する事でChatGPTを使って意図した図を作成できます。

しかし、生成したコードはそのままでは実行できないことがあります。そのため、生成されたコードが問題ないか検証と確認は人が行うのが良いでしょう。つまり、生成したコードに対してもコードレビューが必要です。

色々と実験している中で余りにも重いコードができてしまうことがありました。また、同じプロンプトに対しても常に同じコードではなく、違うコードが生成されることがあります。APIや参照する定数までも異なるコードが生成されることがあります。

生成系AIはそういった特徴も踏まえて利用するのが良いでしょう。

著書紹介

Authored Books

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Akira Hayashi (林 晃)のアバター Akira Hayashi (林 晃) Representative(代表), Software Engineer(ソフトウェアエンジニア)

アールケー開発代表。Appleプラットフォーム向けの開発を専門としているソフトウェアエンジニア。ソフトウェアの受託開発、技術書執筆、技術指導・セミナー講師。note, Medium, LinkedIn
-
Representative of RK Kaihatsu. Software Engineer Specializing in Development for the Apple Platform. Specializing in contract software development, technical writing, and serving as a tech workshop lecturer. note, Medium, LinkedIn

目次