0
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?

半導体ウェハマップの可視化

0
Last updated at Posted at 2026-08-24

膜厚の偏差(Deviation)をヒートマップで可視化する

はじめに

半導体製造工程において、ウェハ上の膜厚ムラや欠陥の分布を可視化するための「ウェハマップ」は非常に重要なツールです。

今回は、Pythonを用いて、散布図的な点データから「連続した色(ヒートマップ)」へと変換し、平均値からの偏差(Deviation)を強調して描画するスクリプトを作成しました。

解決した課題

  1. 離散データの補間: 単純なドットのプロットではなく、scipy.griddata を用いて点と点の間の色を埋め、滑らかなヒートマップにする。
  2. 偏差の可視化: 生データ(mm)ではなく、平均値からの差分(nm)を抽出することで「異常」を見つけやすくする。
  3. 高度なカスタマイズ:
    • カラーマップによる色のコントロール(coolwarm 等)。
    • 範囲の固定(vmin, vmax)により、複数ウェハの比較を可能にする。
    • 背景透過や、特定の半径でのカットなど、レポートへの貼り付けやすさを考慮した出力。

使用技術

  • Python 3.x
  • Pandas: データ解析・CSV読み込み
  • NumPy: 数値計算
  • SciPy: 線形補間(griddata)
  • Matplotlib: 高度な可視化

実装のポイント

1. 平均からの偏差への変換

生の膜厚データは非常に近い数値で推移するため、そのままでは色の変化がわかりにくいことがあります。平均値を算出し、各地点を「差分」に置き換えることで、「どこが異常か(高いか低いか)」を直感的に判断できるマップに変換します。

2. グリッドによる補間 (Interpolation)

散布図ではデータがない場所が空いてしまいます。scipy.griddata を用いて高解像度のグリッドを作成し、その上に元のデータをマッピングすることで、隙間のない滑らかなグラデーションを生成します。

3. カラーマップと範囲の固定

「異常がある=赤」といった意図を反映させるため、カラーマップに coolwarm を採用。また、vmin, vmax をあらかじめ設定することで、複数のウェハ間でも同一のスケールで比較できるようにしています。

サンプルコード

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from scipy.interpolate import griddata

# ==========================================
# 設定項目 (ここを書き換えることで動作を調整)
# ==========================================
CONFIG = {
    "input_file": "wafermap.csv",             # 入力ファイル名
    "output_file": "wafer_deviation_map.png", # 出力ファイル名
    
    # 【ウェハの形状設定】
    "wafer_radius": 150,                      # ウェハの半径
    "grid_res": 300,                         # ヒートマップの解像度(大きいほど滑らか)
    
    # 【ヒートマップの色と範囲の設定】
    "cmap": "coolwarm",                      # カラーマップ ('coolwarm', 'jet', 'viridis' など)
    "vmin": -3.0,                            # 最小値(カラーバーの底)
    "vmax": 3.0,                             # 最大値(カラーバーの頂点)
    
    # 【背景と透明度の設定】
    "bg_color": "#f0f0f0",                   # 背景色 (例: '#ffffff', 'gray' など)
    "is_transparent": False,                  # 背景を透明にするか (True=透ける, False=指定の色で塗りつぶす)
    
    # 【カラーバーのデザイン】
    "cbar_shrink": 0.8,                     # カラーバーの高さ(0.0〜1.0)
    "cbar_pad": 0.02,                       # カラーバーとグラフの距離
    "cbar_label": "Deviation from Mean (nm)", # カラーバーのラベル名
    
    # 【描画オプション】
    "show_outline": True,                    # ウェハの外周線を描画するか
    "show_axes": True,                      # 軸(目盛り、枠線)を表示するか
}

def create_wafer_map():
    # --- 1. データ読み込み ---
    try:
        # 日本語が含まれる場合を考慮して cp932 を指定
        df = pd.read_csv(CONFIG["input_file"], encoding='cp932')
        print(f"Successfully loaded {CONFIG['input_file']}")
    except Exception as e:
        print(f"Error loading file: {e}")
        return

    # --- 2. データ処理(平均からの差分計算) ---
    original_data = df['膜厚(nm)'].values
    avg_value = original_data.mean()
    diff_data = original_data - avg_value
    print(f"Average Thickness: {avg_value:.2f} nm")

    # --- 3. ヒートマップ用グリッド生成と補間 ---
    radius = CONFIG["wafer_radius"]
    # ここを正しく修正しました:CONFIG["grid_res"] を使用します
    xi = np.linspace(-radius, radius, CONFIG["grid_res"])
    yi = np.linspace(-radius, radius, CONFIG["grid_res"])
    X, Y = np.meshgrid(xi, yi)

    # 補間処理(点データから面データを作成)
    Z = griddata((df['X'].values, df['Y'].values), diff_data, (X, Y), method='linear')

    # ウェハ形状のマスク(半径外をカット)
    dist_from_center = np.sqrt(X**2 + Y**2)
    Z[dist_from_center > radius] = np.nan

    # --- 4. 描画準備 ---
    fig, ax = plt.subplots(figsize=(10, 10))
    
    # 背景設定の反映
    if CONFIG["is_transparent"]:
        # 透明にする場合:透過度を調整
        fig.patch.set_alpha(0.0)
        ax.patch.set_alpha(0.0)
    else:
        # 指定された色で塗りつぶす場合
        fig.patch.set_facecolor(CONFIG["bg_color"])
        ax.set_facecolor(CONFIG["bg_color"])

    # 軸の非表示設定(目盛り、枠線を消す)
    if not CONFIG["show_axes"]:
        ax.axis('off')

    # --- 5. ヒートマップの描画 ---
    im = ax.imshow(Z, extent=[-radius, radius, -radius, radius],
                    origin='lower', cmap=CONFIG["cmap"], 
                    interpolation='bilinear', 
                    vmin=CONFIG["vmin"], vmax=CONFIG["vmax"])

    # ウェハの外周線を描画
    if CONFIG["show_outline"]:
        circ = Circle((0, 0), radius, color='black', fill=False, linewidth=2)
        ax.add_patch(circ)

    # --- 6. カラーバーの設定 ---
    cbar = fig.colorbar(im, ax=ax, pad=CONFIG["cbar_pad"], shrink=CONFIG["cbar_shrink"])
    cbar.set_label(CONFIG["cbar_label"])

    # --- [将来用:軸やタイトルなど] ---
    # 必要に応じて以下を有効にしてください
    # ax.set_title("Wafer Thickness Deviation Map", fontsize=15)
    # ax.set_xlabel("X coordinate")
    # ax.set_ylabel("Y coordinate")

    # --- 7. 保存処理 ---
    # 背景が透明な場合は facecolor='none' を指定して透過を維持
    save_face = None if CONFIG["is_transparent"] else CONFIG["bg_color"]
    plt.savefig(CONFIG["output_file"], dpi=300, bbox_inches='tight', facecolor=save_face)
    print(f"Success! Map saved as {CONFIG['output_file']}")

if __name__ == "__main__":
    create_wafer_map()

サンプルデータ

X,Y,膜厚(nm)
0,0,102.1
0,35,101.8
24.7,24.7,101.9
35,0,101.7
24.7,-24.7,101.9
0,-35,101.6
-24.7,-24.7,101.8
-35,0,101.7
-24.7,24.7,102
0,70,100.7
26.8,64.7,100.9
49.5,49.5,101
64.7,26.8,100.6
70,0,100.5
64.7,-26.8,100.8
49.5,-49.5,100.6
26.8,-64.7,100.7
0,-70,100.4
-26.8,-64.7,100.5
-49.5,-49.5,100.8
-64.7,-26.8,100.6
-70,0,100.4
-64.7,26.8,100.7
-49.5,49.5,100.5
-26.8,64.7,100.9
0,105,99.2
52.5,90.9,99.1
90.9,52.5,98.9
105,0,98.8
90.9,-52.5,99.3
52.5,-90.9,99
0,-105,98.7
-52.5,-90.9,98.9
-90.9,-52.5,99.1
-105,0,98.6
-90.9,52.1,99
-52.5,90.9,99.3
0,140,97.2
70,121.2,97
121.2,70,96.8
140,0,96.5
121.2,-70,96.9
70,-121.2,97.1
0,-140,96.7
-70,-121.2,97.2
-121.2,-70,96.9
-140,0,96.6
-121.2,70,97
-70,121.2,97.3

出力結果(例1)

設定
    # 【背景と透明度の設定】
    "bg_color": "#f0f0f0",                   # 背景色 (例: '#ffffff', 'gray' など)
    "is_transparent": False,                  # 背景を透明にするか (True=透ける, False=指定の色で塗りつぶす)
    
    # 【描画オプション】
    "show_outline": True,                    # ウェハの外周線を描画するか
    "show_axes": True,  

wafer_deviation_map.png

出力結果(例2)

設定
    # 【背景と透明度の設定】
    "bg_color": "#f0f0f0",                   # 背景色 (例: '#ffffff', 'gray' など)
    "is_transparent": True,                  # 背景を透明にするか (True=透ける, False=指定の色で塗りつぶす)
    
    # 【描画オプション】
    "show_outline": False,                    # ウェハの外周線を描画するか
    "show_axes": False,  

wafer_deviation_map.png

まとめ

本スクリプトでは、単なる「点の可視化」から一歩踏み込み、分析に耐えうるヒートマップの生成を自動化しました。

特に scipy.griddata を用いた補間と、vmin/vmax によるカラースケールの固定は、製造現場におけるデータの比較において非常に強力な武器になります。

今後、このスクリプトをベースに、複数ウェハの一括処理などの拡張も検討しています。


0
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
0
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?