Chris Parmer — home

Wafer parametric contour

Semiconductor — oxide thickness, computed

Example from the compendium of canonical charts

Semiconductor — Wafer parametric contour (oxide thickness, computed)

Python Code

"""Semiconductor — Wafer parametric contour (oxide thickness, computed)."""


import numpy as np
import plotly.graph_objects as go


def generate():
    rng = np.random.default_rng(0)

    # Wafer at normalized coords: x,y ∈ [-1,1], circular mask r ≤ 1
    N = 50
    x = np.linspace(-1, 1, N)
    y = np.linspace(-1, 1, N)
    X, Y = np.meshgrid(x, y)
    R = np.sqrt(X**2 + Y**2)

    # Oxide thickness model: P(x,y) = 100 - 8r² + 2x - y + noise (Angstroms)
    noise = rng.normal(0, 0.5, X.shape)
    P = 100 + (-8) * R**2 + 2 * X + (-1) * Y + noise

    # Apply circular mask
    P[R > 1] = np.nan

    print(f"  P range (excl NaN): {np.nanmin(P):.1f} – {np.nanmax(P):.1f} Å")

    fig = go.Figure()

    # Contour fill
    fig.add_trace(go.Contour(
        x=x,
        y=y,
        z=P,
        colorscale="RdYlGn",
        zmid=100,
        contours=dict(
            start=float(np.nanmin(P)),
            end=float(np.nanmax(P)),
            size=2,
            showlabels=True,
            labelfont=dict(size=9, color="black"),
        ),
        colorbar=dict(
            title="Thickness (Å)",
            thickness=16,
        ),
        hovertemplate="x: %{x:.2f}<br>y: %{y:.2f}<br>Thickness: %{z:.1f} Å<extra></extra>",
    ))

    # Draw wafer edge circle
    theta = np.linspace(0, 2 * np.pi, 300)
    fig.add_trace(go.Scatter(
        x=np.cos(theta),
        y=np.sin(theta),
        mode="lines",
        line=dict(color="black", width=2),
        showlegend=False,
        hoverinfo="skip",
    ))

    # Notch mark at bottom (270°)
    fig.add_trace(go.Scatter(
        x=[0],
        y=[-1.0],
        mode="markers",
        marker=dict(symbol="triangle-down", size=10, color="black"),
        showlegend=False,
        hoverinfo="skip",
    ))

    fig.update_layout(
        xaxis=dict(
            title="Wafer X (norm.)",
            range=[-1.1, 1.1],
            scaleanchor="y",
            constrain="domain",
            zeroline=True,
            zerolinewidth=1,
            showgrid=False,
        ),
        yaxis=dict(
            title="Wafer Y (norm.)",
            range=[-1.15, 1.1],
            constrain="domain",
            zeroline=True,
            zerolinewidth=1,
            showgrid=False,
        ),
        margin=dict(t=20, b=60, l=60, r=80),
        annotations=[
            dict(
                text="Oxide thickness (Å) — Level-1 model: 100−8r²+2x−y+noise",
                x=0.5, y=1.04,
                xref="paper", yref="paper",
                showarrow=False,
                font=dict(size=10),
            )
        ],
    )

    return fig


if __name__ == "__main__":
    generate()

Made with Plotly