2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

あえて共テのグラフをTeXで組む

2
Posted at

はじめに

共通テストの問題冊子に載っているグラフは、細い線と明朝の数字で組まれていて、それだけで「共テの図」だとわかります。この記事では、令和8年度(2026年)の共通テスト「情報Ⅰ」から2つの図を選び、あえてTikZで組み直します。

  • 第3問の図11(画像の各階調のヒストグラム)
  • 第4問の図2(2つのグループの箱ひげ図)

元の図は、大学入試センターが公開している問題冊子のPDFに載っています。各節の最初に原本の図を、最後にTikZで組んだ完成形と、両者を並べた図を載せています。画像の左上には「原本」「TikZ」のラベルを付け、画像の下にもどちらの図かを書きました。

環境

TeX Live 2026(LuaHBTeX 1.24.0)で確かめています。図はstandaloneクラスで組むので、lualatexにかけると図の大きさぴったりのPDFができます。

共テの問題冊子は、本文も図の数字も明朝体で、軸の名前のような見出しだけがゴシック体の太字です。そこで、どちらの図も原ノ味フォントを読み込み、標準の明朝体のまま組んでいます。

\usepackage[haranoaji]{luatexja-preset}

図11 階調のヒストグラム

図11は、グレースケール画像の画素を、黒(0)から白(255)までの256階調ごとに数えたヒストグラムです。熊のぬいぐるみの写真で、熊より明るい背景が右の高い山、熊が左の低い山になっています。下の矢印⓪〜④のどの範囲を選べば背景だけを選べるかを問う問題でした。

原本の図11
原本(令和8年度大学入学共通テスト 本試験「情報Ⅰ」第3問 図11、大学入試センター)

データを用意する

ヒストグラムは、画像の画素を階調ごとに数えたデータから描くものです。そこで、形を似せて描くのではなく、データをファイルにしてTikZに流し込みます。

データは、1行に「階調 値」を書いたテキストファイルにします。値は、いちばん多い階調を1とした比です。

hist11.dat(抜粋)
51 0.0
52 0.011
53 0.011
⋮
214 1.0
215 1.0
216 0.9724

階調0から255まで256行あり、51までは0、52から棒が始まり、214と215がいちばん高くなっています。

この記事のhist11.datは、元の画像の画素データではなく、原本の図11の棒の高さを読み取って作ったものです。読み取りは、AI(Claude Opus 5.5)が行いました。

TikZで組む

hist256.tex
\documentclass[tikz,border=3mm]{standalone}
\usepackage[haranoaji]{luatexja-preset}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}[x=.25mm, y=50mm]
  \fill[black!85] (0,0) -- plot[const plot] file {hist11.dat} -- (255,0) -- cycle;
  \draw[black!85, line width=1pt] (0,0) -- (255,0);
  \shade[left color=black, middle color=black!60, right color=white] (0,-.065) rectangle (255,-.025);
  \draw (0,-.065) rectangle (255,1.02);
  \node[left] at (0,-.045) {黒};
  \node[right] at (255,-.045) {白};
  \node[left, align=center, font=\gtfamily\bfseries] at (-2,.5) {画\\素\\数};
  \node[below, font=\gtfamily\bfseries] at (127.5,-.07) {階調};
  \foreach \a/\b/\y/\n in {0/55/-.25/0, 55/187/-.25/1, 187/255/-.25/2, 127/214/-.33/3, 55/255/-.41/4}
    \draw[{Bar[width=4mm]Latex[length=2.5mm]}-{Latex[length=2.5mm]Bar[width=4mm]}]
      (\a,\y) -- (\b,\y) node[midway, circle, draw, fill=white, inner sep=.6pt, font=\sffamily\small] {\n};
  \node at (127.5,-.52) {図11\quad 図9の各階調のヒストグラム};
\end{tikzpicture}
\end{document}

座標を階調の単位にする

\begin{tikzpicture}[x=.25mm, y=50mm]

横の1単位を0.25mmにして、横の座標がそのまま階調の値になるようにしています。0から255までで約64mmです。データはいちばん高い棒を1とした比なので、縦の1単位を50mmにすると、いちばん高い棒が50mmになります。

データの値をそのまま座標として使えるので、ファイルの中身を変換せずに描けます。矢印の端も「55」「187」のように階調の値で書けます。

データを流し込む

\fill[black!85] (0,0) -- plot[const plot] file {hist11.dat} -- (255,0) -- cycle;

hist11.datは256行あり、1行が1つの階調に対応しています。この1行だけで、256行すべてを読んでヒストグラムを描いています。

plot fileは、ファイルを1行ずつ読み、各行の1つ目の数をx座標、2つ目の数をy座標とする点にします。256行あるので点は256個になり、次のように座標を手で並べたのと同じになります。

plot coordinates {(0,0.0) (1,0.0) … (51,0.0) (52,0.011) (53,0.011) … (214,1.0) (215,1.0) … (255,0.0074)}

図の単位は、横の1階調を0.25mm、縦の1を50mmにしているので、たとえば(214, 1.0)は、右へ53.5mm、上へ50mmの点になります。

const plotを付けると、点と点を斜めの線では結ばず、同じ高さのまま次の点のx座標まで横に進み、そこで縦に上がる(下がる)階段状の線にします。点が1階調ごとに並んでいるので、段の1つがちょうど1階調の幅になり、その段が棒に見えます。

階調48から62のあたりを拡大し、データの点を赤で描くと、次のようになります。

const plotの拡大
TikZで組んだ拡大図。赤い点がhist11.datの各行

51行目の「51 0.0」から52行目の「52 0.011」へは、高さ0のままx=52まで横に進み、そこで0.011まで上がります。そのあと「57 0.0203」の点まで高さ0.011のまま進むので、階調52から56は同じ高さの段になります。これを256点ぶん繰り返すと、ヒストグラムの外形が1本の線になります。

1行で済むのは、ファイルを1行ずつ読むループを、TikZが内部で代わりに受け持っているからです。plot fileは、TikZの土台であるPGFのpgfplotxyfileという命令に置き換えられます。この命令が、ファイルを1行ずつ読んで点をつなげる処理を、ファイルの終わりまで繰り返します。256行を読むforeachのようなループを、自分で書く必要はありません。

また、TikZのパスは「始点、線、線、……、閉じる」と、1つの命令の中で好きなだけ続けられます。この行を部品ごとに分けると、次のようになります。

\fill[black!85]
  (0,0)
  -- plot[const plot] file {hist11.dat}
  -- (255,0)
  -- cycle;

原点から始め、plotの部分で256点ぶんの階段をつなぎ、右下の角(255, 0)を通って、cycleで始点に戻って閉じています。パスの中身は数百本の線分になりますが、書くのは1行です。

fillは、パスができあがってから、囲まれた内側を1回で塗ります。棒を256本の長方形として描くなら、256回の描画とループが要ります。ここでは外形を1本の線として作り、1回で塗るので、ループを書かずに済みます。棒の間に白い隙間が出ないのもこのためで、元の図も棒の間に隙間がなく、黒い面のように見えるので、この描き方のほうが近くなります。

元の図の山の上端にある細かいギザギザも、データにそのまま入っているので、描き方で作り込む必要はありません。

データを流し込んだ段階
TikZで組んだ途中段階(1/2)

黒から白への階調バー

\shade[left color=black, middle color=black!60, right color=white] (0,-.065) rectangle (255,-.025);

横軸の下の、黒から白へ変わる帯はshadeで塗っています。左端を黒、右端を白にするだけだと、真ん中が明るすぎて元の図と比べて全体が白っぽく見えます。元の図は左の3分の1ほどがほぼ黒なので、真ん中の色を黒60%にして、暗い部分を長くしています。

両端だけ指定した階調バーと、真ん中も指定した階調バー
TikZで組んだ階調バー。上が両端の色だけ、下が真ん中の色も指定したもの

縦書きの「画素数」

\node[left, align=center, font=\gtfamily\bfseries] at (-2,.5) {画\\素\\数};

縦軸の名前は、1文字ずつ改行して縦に並べています。align=centerを付けると、ノードの中で改行が使えるようになります。3文字なら、縦書きの仕組みを使うよりこのほうが手軽です。書体は、見出しなのでゴシック体の太字にしています。

階調バーと軸の名前を足すと、次のようになります。

階調バーと軸の名前を足した段階
TikZで組んだ途中段階(2/2)

選択肢の矢印

\foreach \a/\b/\y/\n in {0/55/-.25/0, 55/187/-.25/1, 187/255/-.25/2, 127/214/-.33/3, 55/255/-.41/4}
  \draw[{Bar[width=4mm]Latex[length=2.5mm]}-{Latex[length=2.5mm]Bar[width=4mm]}]
    (\a,\y) -- (\b,\y) node[midway, circle, draw, fill=white, inner sep=.6pt, font=\sffamily\small] {\n};

5本の矢印は、始まりの階調・終わりの階調・高さ・番号の4つ組をforeachで回して描いています。

矢印の両端は、arrows.metaライブラリの矢じりを2つ重ねて作っています。Barは縦の短い線、Latexは塗りつぶした三角形の矢じりです。始点側は「縦線のあとに矢じり」、終点側は「矢じりのあとに縦線」の順に書くと、範囲の端を縦線で示し、その内側に矢じりが付いた形になります。

番号は、線の中央に置いた丸いノードです。白で塗りつぶしているので、ノードの下を通る線が隠れ、線が番号の丸で途切れて見えます。丸囲み数字の文字を使わずに丸をノードで描いているのは、丸の大きさと線の太さを図に合わせて決められるからです。

矢印と図の番号を足して、図11の完成です。

TikZで組んだ図11
TikZで組んだ完成形

原本と並べると、次のようになります。

原本とTikZの図11を並べたもの
左が原本、右がTikZで組んだ完成形

図2 2つのグループの箱ひげ図

図2は、平均気温の和から推定した桜の開花日(400度開花推定日)と実際の開花日との差を、観測点の2つのグループごとに箱ひげ図にしたものです。G₁は2月1日以降に平均気温が氷点下の日があった観測点、G₂はそれ以外の観測点です。目盛ごとの縦の点線が、箱の後ろを通っています。

原本の図2
原本(令和8年度大学入学共通テスト 本試験「情報Ⅰ」第4問 図2、大学入試センター)

データを用意する

箱ひげ図も、データをファイルにしてTikZに流し込みます。1行に1つのグループを書き、名前、最小値、第1四分位数、中央値、第3四分位数、最大値をスラッシュで区切って並べます。行の終わりのコンマは、グループの区切りです。

box.dat
G$_1$/3/7/16/23/30,
G$_2$/-12/-5/-1/3/6

この形は、TikZのforeachがそのまま読めるリストの書き方です。グループ名の添字は、数式モードで書いておきます。

この記事のbox.datは、観測点ごとの元のデータから計算したものではなく、原本の図2の箱やひげの端の位置を読み取って作ったものです。読み取りは、AI(Claude Opus 5.5)が行いました。読み取った値は、どれもちょうど整数になりました。

TikZで組む

boxplot.tex
\documentclass[tikz,border=3mm]{standalone}
\usepackage[haranoaji]{luatexja-preset}
\usepackage{catchfile}
\CatchFileDef\boxes{box.dat}{}
\begin{document}
\begin{tikzpicture}[x=2mm, y=12mm, line width=.8pt]
  \foreach \x in {-15,-10,...,30} {
    \draw[dashed, thin] (\x,.4) -- (\x,2.75);
    \node[below] at (\x,.4) {$\x$};
  }
  \foreach \g/\lo/\qa/\md/\qb/\hi [count=\i] in \boxes {
    \pgfmathsetmacro\y{3.5-1.2*\i}
    \draw[|-|] (\lo,\y) -- (\hi,\y);
    \draw[fill=white] (\qa,\y-.3) rectangle (\qb,\y+.3);
    \draw (\md,\y-.3) -- (\md,\y+.3);
    \node[left] at (-16,\y) {\g};
  }
  \node at (7.5,-.45) {図2\quad 400度開花差に関する箱ひげ図};
\end{tikzpicture}
\end{document}

横の1単位を2mmにしているので、データの値をそのまま横の座標に使えます。線の太さは、箱ひげ図に合わせて図全体を0.8ptにしています。

箱の後ろを通る点線

\foreach \x in {-15,-10,...,30} {
  \draw[dashed, thin] (\x,.4) -- (\x,2.75);
  \node[below] at (\x,.4) {$\x$};
}

目盛の点線は、箱ひげ図より先に、細い線で描いています。点線だけを描いた段階では、次のようになります。

目盛の点線だけを描いた段階
TikZで組んだ途中段階(1/2)

このあと描く箱は白で塗りつぶすので、点線は箱の外では見え、箱の中では隠れます。元の図も、点線が箱の手前を通らないようになっています。

目盛の数字は、数式モードで書いています。こうすると、負の数の前に付く記号が、ハイフンより長い正しいマイナス記号になります。元の図も、−15や−10の記号は数字と同じくらいの幅があります。

データを流し込む

\usepackage{catchfile}
\CatchFileDef\boxes{box.dat}{}

catchfileパッケージのCatchFileDefは、ファイルの中身を文字列として読み込み、それを本体にしたマクロを作ります。1つ目の引数が作るマクロの名前、2つ目が読み込むファイル、3つ目は読み込む前に実行する設定で、今回は何もしないので空にしています。

ファイルの改行は空白に置き換わるので、box.datの2行は1行につながります。結果として、次のように手で書いたのと同じマクロができます。

\def\boxes{G$_1$/3/7/16/23/30, G$_2$/-12/-5/-1/3/6 }

次に、このマクロをforeachに渡します。

\foreach \g/\lo/\qa/\md/\qb/\hi [count=\i] in \boxes {

boxesの中身はリストそのものなので、このforeachは、次のようにリストを直接書いたのと同じ動きをします。

\foreach \g/\lo/\qa/\md/\qb/\hi [count=\i] in {G$_1$/3/7/16/23/30, G$_2$/-12/-5/-1/3/6} {

foreachは、コンマで区切られた1グループずつを取り出し、スラッシュで区切られた6つの値を、名前・最小値・第1四分位数・中央値・第3四分位数・最大値の変数に入れます。count=\iを付けているので、何番目のグループかも1から数えて受け取れます。1回目のループでは、名前にG₁、最小値に3、第1四分位数に7、中央値に16、第3四分位数に23、最大値に30が入り、何番目かを表す変数は1になります。2回目は、G₂の行の値が入ります。

つまり、データを図のコードに直接書く代わりに、別のファイルに分けて読み込んでいるだけです。データを変えたいときは、box.datだけを書き換えれば済みます。

箱ひげ図を描く

\pgfmathsetmacro\y{3.5-1.2*\i}
\draw[|-|] (\lo,\y) -- (\hi,\y);
\draw[fill=white] (\qa,\y-.3) rectangle (\qb,\y+.3);
\draw (\md,\y-.3) -- (\md,\y+.3);
\node[left] at (-16,\y) {\g};

1行目で、グループの縦の位置を決めます。1番目のグループが2.3、2番目が1.1になるように、1.2ずつ下げています。

2行目のひげは、最小値から最大値まで1本の線を引いています。矢印の種類に両端とも縦線を指定すると、線の両端に短い縦線が付き、ひげの端の形になります。

3行目の箱は、第1四分位数から第3四分位数までの長方形です。ひげを先に描いておき、箱を白で塗りつぶして重ねているので、箱の中を通るひげは隠れます。ひげを箱の左右で2本に分けて描かなくて済みます。

4行目で中央値の位置に箱と同じ高さの縦線を引き、5行目で図の左端にグループ名を置いています。

箱を白で塗りつぶさずに描くと、次のようになります。ひげと目盛の点線が、箱の中を通って見えてしまいます。

箱を塗りつぶさずに描いた段階
TikZで組んだ途中段階(2/2)。箱を白で塗らなかった場合

図の番号を足して、図2の完成です。

TikZで組んだ図2
TikZで組んだ完成形

原本と並べると、次のようになります。

原本とTikZの図2を並べたもの
左が原本、右がTikZで組んだ完成形

出典

  • 大学入試センター「令和8年度大学入学共通テスト 本試験 問題 情報Ⅰ」第3問 図11、第4問 図2

Scoring64について

Scoring64の採点画面
Scoring64の採点画面。手書きの記述答案を、満点・0点・部分点のボタンで採点しているところ

Scoring64は、用紙の作成から答案の取り込み・採点・返却までを手元のPCで行う採点アプリで、WindowsとmacOSで動きます。用紙は22科目の共通テスト用マークシートからも作れます。

  • マークシートの読み取り・正誤判定・得点計算・結果CSVの保存は、無料で期限なく使えます。キーは不要で、オフラインで動きます。
  • 用紙作成・記述採点・返却PDFなどは、初回起動から10日間無料で試せます。
  • 次のバージョン1.0.9では、生徒ごとの個人成績票と教師用の成績一覧を、採点結果から自動で組む成績表を追加する予定です。

ダウンロードはこちらから。

数学の問題を参考書のような解答PDFに

Evoltonの画面と、生成した解答PDF

Evoltonは、数学の問題の写真やスクリーンショットをAIが読み取って解き、参考書のようなレイアウトの解答PDFに清書するサービスです。

  • 解答PDFの作成では、写真やスクリーンショットの問題を読み取り、方針・解答・着眼点を組んだPDFにします。
  • 過去問データベースでは、大学、学部、年度の順にたどると、問題と解答のPDFをその場で閲覧・ダウンロードできます。
  • オーダーメイド問題集では、欲しい問題を言葉で伝えると、条件に合う過去問を選んで問題集にまとめます。

→ Evoltonを試す

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?