ChatGPTとRで、手持ちのレンズの焦点距離をまとめた図を作る
背景と趣旨
ある日、手持ちのレンズの焦点距離をまとめた図を作ろうと思い立った。図を作成することで手持ちのレンズの焦点距離が必要十分であることを可視化し、なんとなく新しいレンズを購入したいという愚かな願望を抑制しようと考えたのである。
図を作るだけならExcelでもPowerpointでもよいが、どうせならプログラミングで出力しメンテナンスを簡単にしたいなと思った。そこで、ChatGPT(無料版のGPT 3.5)とオープンソースの統計解析ソフトウェア「GNU R(以下、R)」を使って図を出力することにした。
結果
こんな図を出力することができた。
うーん、超望遠単焦点レンズが欲しい。Sigmaの500mmとか……ほら……x軸を600mmまで描画してごらんなさい……欠けていることがよくわかるだろう?
前提
この記事では以下の2つを前提とする。
前提1: PCにRがインストール済み
Rが使用できる環境が必要である。この記事ではR 4.3.1を使用して図を出力した。Rの導入方法は下記をご参照いただきたい。
前提2: レンズ名一覧を作成済み
焦点距離(mm)の情報を含むレンズ名一覧が必要である。一覧は自分が図を作成したい順序で記載しておく。こんな図を出力したくなるような人なら既に作成済みだろう。
データセットの作成
さて、目標とする図を出力するためには、レンズ名、焦点距離の始点および焦点距離の終点の情報が必要である。加えて、私の場合はレンズをフォーカス方式で"AF" or "MF"という2つのカテゴリに分類したいと考えた。そこで、以下の2ステップでデータセットとなるCSVファイルを作成した。
STEP1: ChatGPTによるCSVファイル生成
焦点距離(mm)の情報を含むレンズ名一覧をChatGPTで加工し、"lens_name", "forcal_length_start", "forcal_length_end" という3つの列を持つCSVファイル(カンマ区切り)を生成する。
STEP2: 分類の追記
作成したCSVファイルに4つめの列として"focus_method"を追加し、"AF" または "MF" というカテゴリを記載する。
STEP1: ChatGPTによるCSVファイル生成
ChatGPTに以下のようなプロンプトを入力し、CSVファイルの中身を生成する。
出力結果は以下のようなplaintextとなる。この中身をコピーし、CSVファイルを作成する。今回はファイル名を「K.csv」とした。
STEP2: カテゴリ分類の追記
先ほど作成したK.csvを適当なエディタ(メモ帳など)で開き、4列目として "focus_method" を追記する。以下のようになる。
図の出力
さて、いよいよRで図を出力する。まずは解析に必要なパッケージを読み込む。使用する主なパッケージはdplyrとggplot2の2つである。
# 必要なパッケージを読み込む
if (!requireNamespace("pacman", quietly = TRUE)) {
install.packages("pacman")
}
library(pacman)
p_load(dplyr, ggplot2)
つぎに、作成したデータセット(K.csv)を読み込んでから"order"という列を追加し、データセットの冒頭から順に連番(1, 2, 3…)を付与する。
read.csv()関数の値はデータセットの相対パスまたは絶対パスであり、適宜変更が必要だ。
"order"列はレンズの並び順を明示するために使用する。CSVファイルを作成する段階で"order"列を作成しても良いが、レンズは増えるものなのでこの辺りはRで自動処理する。
# CSVファイルを読み込み、"order"列を追加して連番を割り当てる
lens_data <- read.csv("./data/K.csv") %>%
transform(order = 1:nrow(.))
では、ggplot2で図を出力する。
# プロットを生成する
## データセットとマッピングを指定する
p <- lens_data %>%
ggplot(aes(
x = focal_length_start,
xend = focal_length_end,
y = order,
yend = order,
color = focus_method
))
## グラフの種類を指定する
p <- p +
geom_vline(xintercept = seq(0, 450, 50),
linetype = "dashed", linewidth = 0.25, color = "gray80") +
geom_point(aes(x = focal_length_start), size = 1) +
geom_point(aes(x = focal_length_end), size = 1) +
geom_segment(linewidth = 2) +
geom_text(aes(label = lens_name, x = 0), size = 2, hjust = 1, nudge_x = -10)
## グラフの見た目を調整する
p <- p +
scale_color_manual(values = c("AF" = "darkgreen", "MF" = "darkorange")) +
scale_x_continuous(breaks = seq(0, 450, 50)) +
scale_y_reverse() +
coord_cartesian(xlim = c(-300, 450)) +
theme_classic() +
theme(legend.title = element_blank(),
plot.title = element_text(face = "bold"),
axis.text.y = element_blank(), axis.line.y = element_blank(), axis.ticks.y = element_blank(),
panel.grid.major.y = element_blank(), panel.background = element_rect(fill = "gray95"))
## グラフのタイトルや軸ラベルなどを指定する
p <- p +
labs(x = "Focal length (mm)", y = "") +
ggtitle("K mount")
## 右下にボックスとテキストを追加する(リアコンバーター用)
p <- p +
geom_rect(aes(xmin = 180, xmax = 450, ymin = max(order) - 5.5, ymax = max(order) - 6.5),
fill = "gray85", color = "gray85") +
geom_text(aes(x = (180 + 450)/2, y = max(order) - 6,
label = "HD PENTAX-DA AF REAR CONVERTER 1.4x AW"), color = "red",
size = 2, vjust = 0.5, hjust = 0.5)
## プロットを表示する
p
出力結果は冒頭に示した通りである。"geom", "scale", "coord" から始まる関数群の数値部分や"label"に記載されたテキストを変更することで、様々なレンズシステムに対応できる。コードの詳細な解説やカスタマイズ方法は、ChatGPTなどを利用して確認して欲しい。
まとめ
この記事ではChatGPTとRを使用して、手持ちのレンズの焦点距離を図にまとめる方法を示した。結果として新たなレンズが欲しくなったので大失敗である。皆様も試してみてほしい。そして一緒に深いレンズ沼に堕ちよう。