【Excel】グラフ作成の効率化テクニック
はじめに
測定データのグラフ化において、手作業での書式設定はかなり面倒です。
- 複数グラフ間での書式統一が困難(フォントサイズ、色、軸範囲等のバラつき)
- 仕様変更時の修正コストが高い(全グラフの個別編集が必要)
特に、論文・レポート用に同一フォーマットで大量のグラフを作成する場合、この非効率性は顕著です。
解決策:
VBAマクロによる書式の自動適用が有効ですが、従来はコーディング知識が必要でした。本記事では、LLM(Claude、ChatGPT、Codex等)を活用し、自然言語での指示からVBAコードを生成する手法を紹介します。
実装例として、周波数応答グラフ用のマクロ(対数軸設定、Y軸範囲の自動調整、系列の透明度グラデーション)と、効果的なプロンプトの書き方を示します。
実装方針:AI + VBA
なぜVBA?
グラフ書式の自動化には複数の選択肢がありますが、VBAには以下の利点があります。
- Excelファイル内で完結:別途環境構築不要、ファイル共有で設定も配布可能
- 動的な処理が可能:データの最大値を取得して軸範囲を自動設定、など
- 既存ワークフローへの統合:測定データの記録〜グラフ化を一貫してExcel内で実施
AIを使うことで直感性+スループットが両立
VBAコーディングの経験がなくても、以下の手順で実装できます。
- 「こういうグラフにしたい」という仕様を自然言語で記述
- LLMがVBAコードを生成
- 生成されたコードをExcelに貼り付け
- 必要に応じてフィードバックし、コードを修正
重要なのはプロンプト設計です。具体的な数値(RGB値、フォントサイズ等)を指定することで、所望のフォーマットを実現できます。
環境設定
VBAマクロを使うので、まずExcelの開発環境を有効化しましょう。
手順
-
ファイル→オプション→リボンのユーザー設定 - 右側の
開発にチェックを入れる

Excel オプション - 開発タブの有効化
- リボンに追加された
開発タブからVisual Basicを選択 - VBAエディタで
挿入→標準モジュールを選択 - 表示されたコードウィンドウに、後述のマクロをペーストする

VBA エディタ - 標準モジュールへのコード実装
注:マクロを使う場合、マクロ有効ブック(.xlsm)として保存する必要があります。
実装例
実際に私が使っている周波数応答グラフ用のマクロを紹介します。アクティブシート内の全グラフに対して、一括で書式を適用する設計になっています。
マクロの機能概要
- 軸設定:X軸を対数スケール(10Hz〜20kHz)、Y軸を線形スケール(-40dB〜自動上限)
- 書式統一:フォントサイズ、軸線・グリッド線の色と太さを指定
- 系列スタイル:単色(濃紺)+ 透明度グラデーションで最大11系列に対応
- 動的調整:Y軸最大値をデータから自動算出、プロット領域の余白を自動調整
コード全体
Option Explicit
Sub ChangeFontSizeAndBold_NoTitle()
Dim ws As Worksheet
Dim chartObj As ChartObject
Dim chart As chart
Dim fontSize As Integer
Dim series As series
' フォントサイズを指定
fontSize = 16
' 現在のシートを対象にする
Set ws = ActiveSheet
' シート内の全てのグラフオブジェクトに対して処理
For Each chartObj In ws.ChartObjects
Set chart = chartObj.chart
' 枠線(グラフオブジェクト)の枠線をなしに設定
chartObj.ShapeRange.Line.Visible = msoFalse
' プロットエリアの枠線を灰色、太さ1.25に設定
chart.PlotArea.Format.Line.ForeColor.RGB = RGB(120, 120, 120)
chart.PlotArea.Format.Line.Weight = 1.25
' 縦軸の線を灰色、太さ1.25に設定
chart.Axes(xlValue).Format.Line.ForeColor.RGB = RGB(120, 120, 120)
chart.Axes(xlValue).Format.Line.Weight = 1.25
' 横軸の線を灰色、太さ1.25に設定
chart.Axes(xlCategory).Format.Line.ForeColor.RGB = RGB(120, 120, 120)
chart.Axes(xlCategory).Format.Line.Weight = 1.25
' 縦目盛線(主)をグレー、太さ0.5に設定
chart.Axes(xlValue).MajorGridlines.Format.Line.ForeColor.RGB = RGB(160, 160, 160)
chart.Axes(xlValue).MajorGridlines.Format.Line.Weight = 0.5
' 縦目盛線(補助)を薄いグレー、太さ0.5に設定
chart.Axes(xlValue).MinorGridlines.Format.Line.ForeColor.RGB = RGB(225, 225, 225)
chart.Axes(xlValue).MinorGridlines.Format.Line.Weight = 0.5
' 横目盛線(主)をグレー、太さ0.5に設定
chart.Axes(xlCategory).MajorGridlines.Format.Line.ForeColor.RGB = RGB(160, 160, 160)
chart.Axes(xlCategory).MajorGridlines.Format.Line.Weight = 0.5
' 横目盛線(補助)を薄いグレー、太さ0.5に設定
chart.Axes(xlCategory).MinorGridlines.Format.Line.ForeColor.RGB = RGB(225, 225, 225)
chart.Axes(xlCategory).MinorGridlines.Format.Line.Weight = 0.5
' X軸ラベルのフォント設定
chart.Axes(xlCategory).TickLabels.Font.Size = fontSize
chart.Axes(xlCategory).TickLabels.Font.Bold = False
chart.Axes(xlCategory).TickLabels.Font.Color = RGB(0, 0, 0)
' Y軸ラベルのフォント設定
chart.Axes(xlValue).TickLabels.Font.Size = fontSize
chart.Axes(xlValue).TickLabels.Font.Bold = False
chart.Axes(xlValue).TickLabels.Font.Color = RGB(0, 0, 0)
' X軸タイトルの設定
If Not chart.Axes(xlCategory, xlPrimary).HasTitle Then
chart.Axes(xlCategory, xlPrimary).HasTitle = True
End If
chart.Axes(xlCategory, xlPrimary).AxisTitle.Text = "Frequency (Hz)"
chart.Axes(xlCategory, xlPrimary).AxisTitle.Font.Size = fontSize + 2
chart.Axes(xlCategory, xlPrimary).AxisTitle.Font.Bold = False
chart.Axes(xlCategory, xlPrimary).AxisTitle.Font.Color = RGB(0, 0, 0)
'=== X軸(横軸)対数設定・範囲・目盛 ===
Dim xAx As Axis
On Error Resume Next
Set xAx = chart.Axes(xlCategory, xlPrimary)
On Error GoTo 0
If Not xAx Is Nothing Then
Call SetupLogXAxis(xAx, 10#, 20000#)
End If
' Y軸タイトルの設定
If Not chart.Axes(xlValue, xlPrimary).HasTitle Then
chart.Axes(xlValue, xlPrimary).HasTitle = True
End If
chart.Axes(xlValue, xlPrimary).AxisTitle.Text = "Gain (dB)"
chart.Axes(xlValue, xlPrimary).AxisTitle.Font.Size = fontSize + 2
chart.Axes(xlValue, xlPrimary).AxisTitle.Font.Bold = False
chart.Axes(xlValue, xlPrimary).AxisTitle.Font.Color = RGB(0, 0, 0)
'=== Y軸(縦軸)のスケーリング設定 ===
' 主目盛線:10 dB刻み、補助目盛線:5 dB刻み
' 最小値:-40 dB、最大値:プロットの最大値を10の位で切り上げ
Dim yMax As Double, yMaxCeil As Double
yMax = GetChartMaxY(chart)
yMaxCeil = WorksheetFunction.Ceiling(yMax, 10)
With chart.Axes(xlValue)
.MinimumScaleIsAuto = False
.MaximumScaleIsAuto = False
.MinimumScale = -40
.MaximumScale = yMaxCeil
.MajorUnit = 10
.MinorUnit = 5
.HasMinorGridlines = True
.MajorTickMark = xlOutside
.MinorTickMark = xlOutside
End With
' 凡例の処理
If chart.HasLegend Then
With chart.Legend
With .Font
.Size = fontSize - 2
.Bold = False
.Color = RGB(0, 0, 0)
End With
With .Format.Fill
.ForeColor.RGB = RGB(255, 255, 255)
.Transparency = 0.1
End With
End With
End If
'--- 単色&透明度をシリーズ番号に応じて設定(1~11で不透明度UP) ---
Const BASE_R As Long = 10
Const BASE_G As Long = 62
Const BASE_B As Long = 85
Const MAX_SERIES As Long = 11
Const TRANS_START As Double = 0.65
Const TRANS_END As Double = 0.05
Dim s As series
Dim idx As Long
Dim frac As Double
Dim t As Double
idx = 1
For Each s In chart.SeriesCollection
With s.Format.Line
.Visible = msoTrue
.Weight = 1.75
.ForeColor.RGB = RGB(BASE_R, BASE_G, BASE_B)
frac = WorksheetFunction.Min(idx - 1, MAX_SERIES - 1) / (MAX_SERIES - 1)
t = TRANS_START + (TRANS_END - TRANS_START) * frac
If t < 0 Then t = 0
If t > 1 Then t = 1
.Transparency = t
End With
idx = idx + 1
Next s
' データラベルのフォント設定
For Each series In chart.SeriesCollection
If series.HasDataLabels Then
series.DataLabels.Font.Size = fontSize
series.DataLabels.Font.Bold = False
series.DataLabels.Font.Color = RGB(0, 0, 0)
End If
Next series
'=== グラフタイトルは使用しない ===
' 上部タイトルを無効化
chart.HasTitle = False
' 以前の下部タイトル(BottomTitle)があれば削除
Dim shp As Shape
For Each shp In chart.Shapes
If shp.Name = "BottomTitle" Then
shp.Delete
Exit For
End If
Next shp
' ラベルが詰まりすぎないように、X軸ラベルの更に下に最低パディングを確保
' 第2引数は確保したい余白パディング(ポイント)。フォントサイズ係数的 + 余白を足す。
Call EnsureBottomPadding(chart, fontSize * 0.9 + 8, 0)
Next chartObj
End Sub
Private Sub SetupLogXAxis(xAx As Axis, minVal As Double, maxVal As Double)
' X軸を対数(底10)に設定。値軸の場合のみ MajorUnit=1 を適用。
' カテゴリ軸では MajorUnit は設定不可のため、エラーは無視し補助目盛のみ判定する。
On Error Resume Next
With xAx
.ScaleType = xlLogarithmic
.LogBase = 10
.MinimumScaleIsAuto = False
.MaximumScaleIsAuto = False
.MinimumScale = minVal
.MaximumScale = maxVal
' 値軸(xlValue)なら MajorUnit が設定可。カテゴリ軸ではエラーになるため無視。
.MajorUnitIsAuto = False
Err.Clear
.MajorUnit = 1 ' 1デケード刻み(10^n)
If Err.Number <> 0 Then
' カテゴリ軸など:MajorUnit が非対応 → 何もしない
Err.Clear
End If
' 補助目盛は Excel の対数仕様(2~9倍)を利用
.MinorUnitIsAuto = True
.HasMinorGridlines = True
.MinorTickMark = xlOutside
.MajorTickMark = xlOutside
' ラベルの書式は参照セルに追従
.TickLabels.NumberFormatLinked = True
End With
On Error GoTo 0
End Sub
Private Function GetChartMaxY(ch As chart) As Double
Dim s As series
Dim v As Variant
Dim curMax As Double
Dim tmp As Double
curMax = -1E+308
On Error Resume Next
For Each s In ch.SeriesCollection
v = s.Values
If IsArray(v) Then
tmp = Application.WorksheetFunction.Max(v)
Else
tmp = CDbl(v)
End If
If Err.Number = 0 Then
If tmp > curMax Then curMax = tmp
Else
Err.Clear
End If
Next s
On Error GoTo 0
If curMax = -1E+308 Then
curMax = 0 ' フォールバック
End If
GetChartMaxY = curMax
End Function
Private Sub EnsureBottomPadding(ch As chart, paddingPts As Single, Optional minPlotHeight As Single = 60)
On Error Resume Next
Dim axisBottom As Single
Dim currentGap As Single
Dim diff As Single
' X軸ラベル最下の位置と、ChartArea底とのギャップを取得
axisBottom = ch.Axes(xlCategory).Top + ch.Axes(xlCategory).Height
currentGap = ch.ChartArea.Height - axisBottom
' 目標との差分(+:余白が不足、-:余白が過剰)
diff = paddingPts - currentGap
' 微妙な差分は調整不要
If Abs(diff) <= 0.5 Then GoTo CleanExit
If diff > 0 Then
' --- 余白が足りない:プロットエリアを上に押し上げる(高さを縮める優先) ---
Dim deltaUp As Single
deltaUp = diff
If ch.PlotArea.Height > deltaUp + minPlotHeight Then
ch.PlotArea.Height = ch.PlotArea.Height - deltaUp
Else
' 最低高を守りつつ分をTopを上に上げて確保
Dim needMoveUp As Single
needMoveUp = deltaUp - (ch.PlotArea.Height - minPlotHeight)
ch.PlotArea.Height = minPlotHeight
ch.PlotArea.Top = Application.Max(0, ch.PlotArea.Top - needMoveUp)
End If
Else
' --- 余白が余っている:プロットエリアを下側に拡張^上に移動 ---
Dim needReduce As Single
needReduce = -diff ' 減らしたいギャップ量
' 1) まず高さを伸ばしてギャップを埋める
Dim freeBottom As Single
Dim grow As Single
freeBottom = ch.ChartArea.Height - (ch.PlotArea.Top + ch.PlotArea.Height)
grow = Application.Min(needReduce, Application.Max(0, freeBottom - 1))
If grow > 0 Then
ch.PlotArea.Height = ch.PlotArea.Height + grow
needReduce = needReduce - grow
End If
' 2) まだ余るなら、プロットエリアを下に移動
If needReduce > 0 Then
freeBottom = ch.ChartArea.Height - (ch.PlotArea.Top + ch.PlotArea.Height)
Dim moveDown As Single
moveDown = Application.Min(needReduce, Application.Max(0, freeBottom - 1))
If moveDown > 0 Then
ch.PlotArea.Top = ch.PlotArea.Top + moveDown
End If
End If
End If
CleanExit:
On Error GoTo 0
End Sub
主要な処理の解説
軸範囲の動的設定
yMax = GetChartMaxY(chart)
yMaxCeil = WorksheetFunction.Ceiling(yMax, 10)
GetChartMaxY関数で全系列のデータから最大値を取得し、Ceilingで10dB単位に切り上げることで、データに応じた適切なY軸範囲を設定します。
系列の透明度制御
frac = WorksheetFunction.Min(idx - 1, MAX_SERIES - 1) / (MAX_SERIES - 1)
t = TRANS_START + (TRANS_END - TRANS_START) * frac
系列番号に応じて透明度を線形補間(65%→5%)することで、多数の系列を色を変えずに区別可能にします。
実行方法
- コードを標準モジュールに貼り付け
- グラフを含むシートをアクティブにする
-
Alt + F8でマクロ実行ダイアログを開く -
ChangeFontSizeAndBold_NoTitleを選択して実行
適用結果
マクロ適用前後の比較
デフォルト設定(適用前)

Excel デフォルト設定のグラフ
これはよくないです。学生実験のレポートでよく見かけますね。
課題:
- グラフタイトルが不要
- 軸名が明記されていない
- x軸ラベルの位置が不自然
- フォントが小さく可読性が低い
- グリッド線が太く、データ線より目立つ
- 軸範囲が自動設定で適切でない
- 系列の色が派手で論文向きでない
マクロ適用後

Bode Plot of the Tone Control Circuit — Neck Position, Volume Knob Adjusted
改善点:
- フォント16pt/18ptで視認性向上
- グリッド線を薄いグレーに変更し、データ線を強調
- Y軸範囲を-40dB〜データ最大値+αに自動設定
- 系列を単色+透明度グラデーションで整理
実際の使用例
このマクロは、以下の測定データ記事で実際に使用しています。
複数の測定条件を比較する際に、全グラフで統一したフォーマットを維持できています。
グラフデザインの原則
今回紹介したマクロでは、以下のデザイン原則に基づいてグラフ書式を設定しています。
1. 視覚的階層の構築
要素の太さと濃さで重要度を表現します。
| 要素 | 設定 | 目的 |
|---|---|---|
| データ線 | 1.75pt、濃紺 | <u>最も目立たせる</u> |
| 軸線 | 1.25pt、RGB(120,120,120) | 枠組みを示す |
| 主グリッド線 | 0.5pt、RGB(160,160,160) | 目盛りを補助 |
| 補助グリッド線 | 0.5pt、RGB(225,225,225) | さらに控えめ |
データそのものに視覚的重みを置くことを意識しましょう。グリッド線は必要でなければ外しても構いません。
2. 単色+透明度グラデーション
系列が多い場合(10本以上)、色分けではなく透明度で区別します。
利点:
- モノクロ印刷でも判別可能
- カラーユニバーサルデザインに対応
- フォーマルな印象を維持
注意:系列が交わる場合は、この手法は適していません。交わる場合は系列数を減らして色分けしましょう。
3. 対数軸での目盛り設計
周波数軸(X軸)は対数表示とし、以下を設定します。
- 主目盛:1デケード刻み(10, 100, 1000, 10000 Hz)
- 補助目盛:対数の標準刻み(2, 3, 4, ..., 9の倍数)
- 範囲:10Hz〜20kHz(可聴域をカバー)
[!hint]
周波数軸は対数とすることが原則です。
4. フォントサイズの最適化
用途に応じたフォントサイズを設定します。
| 用途 | 軸ラベル | 軸タイトル | 根拠 |
|---|---|---|---|
| 論文・記事 | 16pt | 18pt | Web表示(800×500px)で可読 |
| プレゼン | 24pt | 27pt | スライド投影時の視認性 |
太字は視覚的に煩雑になるため使用しない方が良いです。
5. グラフタイトルの省略
グラフ内のタイトルは設けず、キャプションで説明します。
根拠:
- 学術論文の標準的な形式(図番号+キャプション)に準拠
- グラフ内スペースをデータ表示領域に充てる
6. 動的な軸範囲設定
Y軸範囲はデータに応じて自動調整します。
yMax = GetChartMaxY(chart)
yMaxCeil = WorksheetFunction.Ceiling(yMax, 10)
.MinimumScale = -40 ' 固定値
.MaximumScale = yMaxCeil ' データ依存
方針:
- 最小値:-40dB固定(S/N比の下限から決定すると良い)
- 最大値:データ最大値を10dB単位で切り上げ
これにより、データの変動範囲に応じた適切なスケールを自動設定できます。
プロンプト設計
LLMに効果的なVBAコードを生成させるには、明確で具体的なプロンプトが必要です。
プロンプトの構成要素
以下の4要素を含めることで、期待通りのコードが得られます。
1. 目的の明示
Excel VBAで、周波数応答グラフを科学論文品質にフォーマットするマクロを作成
2. 技術仕様
- X軸: 対数スケール(10Hz〜20kHz)、グレー軸線 RGB(120,120,120)
- Y軸: 線形スケール(-40dB〜自動上限)、10dB刻み主目盛、5dB刻み補助目盛
3. 処理要件
- アクティブシート内の全グラフに一括適用
- Y軸最大値はデータから自動算出し、10dB単位で切り上げ
4. エラーハンドリング
- 対数軸設定時のカテゴリ軸エラーを適切に処理
- グラフが存在しない場合はスキップ
プロンプト例(簡潔版)
Excel VBAで、周波数応答グラフを科学論文品質にフォーマットするマクロを作成してください。
仕様:
- X軸: 対数(10-20000 Hz)、グレー軸線(RGB 120,120,120)
- Y軸: 線形(-40~自動上限 dB)、10dB刻み主目盛、5dB刻み補助目盛
- グリッド: 主(RGB 160,160,160)、補助(RGB 225,225,225)
- 系列: 全て濃紺(RGB 10,62,85)、透明度は1番目65%→11番目5%でグラデーション
- フォント: 軸ラベル16pt、軸タイトル18pt、全て非太字
- グラフタイトルなし、X軸下に適切な余白を自動確保
アクティブシート内の全グラフに一括適用。
エラーハンドリングを含め、堅牢な実装にしてください。
一度に完璧なコードを生成しなくても、段階的に機能を追加することもできるので、まずは思いつく範囲で書いてみましょう。
実装後の調整
生成されたコードを実行して確認し、必要に応じてフィードバックします。
LLMに適切にコメントアウトを書かせてコードの可読性を上げておいた上で、数値の変更程度であれば自力で修正すると良いです。
まとめ
AI + VBAを使えば、プログラミング経験がなくても論文品質のグラフを量産できます。
プロンプトの書き方には少しコツが要りますが、一度覚えてしまえばスムーズです。
測定データのグラフ化で困っている方は、ぜひ試してみてください。
Discussion