codex/blue-led-injection-structure-and-readout.py

blue-led-injection-structure-and-readout.py
"""Draw a functional InGaN LED, not a historical device reconstruction.

Run from _media; Python 3.14, matplotlib 3.10.7. Opaque white output.
"""
from pathlib import Path

import matplotlib.pyplot as plt
from matplotlib.patches import FancyArrowPatch, FancyBboxPatch, Rectangle


def main():
    plt.rcParams.update({"font.size": 11, "font.family": "DejaVu Sans"})
    fig, ax = plt.subplots(figsize=(11, 7), dpi=120, facecolor="white")
    ax.set(xlim=(0, 11), ylim=(0, 7))
    ax.axis("off")
    fig.subplots_adjust(left=0.015, right=0.985, bottom=0.025, top=0.98)
    ax.text(0.3, 6.65, "Blue LED: electrical injection → light → readout", size=18, weight="bold")
    ax.text(0.3, 6.25, "Representative quantum-well structure; layer thicknesses not to scale", color="#53616d")

    def arrow(start, end, color="#253749", lw=2, style="-|>"):
        ax.add_patch(FancyArrowPatch(start, end, arrowstyle=style, mutation_scale=15,
                                    color=color, linewidth=lw))

    layers = [
        (1.55, 0.65, "Sapphire substrate", "#e6e1ef"),
        (2.20, 0.35, "Buffer: prepares growth", "#d6c3a7"),
        (2.55, 0.80, "n-GaN: electron supply", "#d5e7fa"),
        (3.35, 0.45, "InGaN active quantum well(s)", "#c4d3ff"),
        (3.80, 0.45, "p-AlGaN: carrier confinement", "#f8dfbb"),
        (4.25, 0.70, "p-GaN: hole supply", "#f8e8cf"),
    ]
    for y, height, label, color in layers:
        ax.add_patch(Rectangle((1.1, y), 5.0, height, facecolor=color, edgecolor="#65717b"))
        ax.text(3.6, y + height / 2, label, ha="center", va="center")
    ax.add_patch(Rectangle((1.1, 4.95), 1.2, 0.16, facecolor="#7b838b"))
    ax.add_patch(Rectangle((0.5, 2.65), 0.6, 0.16, facecolor="#7b838b"))
    ax.text(0.4, 5.32, "p contact (+)", size=10)
    ax.text(0.08, 2.95, "n contact (−)", size=10)
    ax.plot([1.7, 1.7, 0.25, 0.25, 1.4],
            [5.11, 5.72, 5.72, 0.69, 0.69], color="#394651", lw=1.6)
    ax.plot([0.8, 0.8, 6.6, 6.6, 6.1],
            [2.65, 1.20, 1.20, 0.69, 0.69], color="#394651", lw=1.6)
    ax.add_patch(FancyBboxPatch((1.4, 0.38), 4.7, 0.62, boxstyle="round,pad=0.12",
                               facecolor="white", edgecolor="#394651"))
    ax.text(3.75, 0.69, "Drive current I; measure terminal voltage V", ha="center", va="center", size=10)
    # Carrier arrows are schematic supply routes, not conventional current arrows.
    arrow((5.6, 2.77), (5.6, 3.47), "#285caa")
    arrow((5.6, 4.78), (5.6, 3.67), "#ab5a16")
    ax.text(6.20, 3.35, "electrons + holes\nrecombine", va="center", size=10)
    arrow((4.6, 3.59), (7.8, 5.48), "#426cd7", 2.8)
    ax.text(6.45, 4.80, "escaped photons", rotation=29, color="#285caa", size=10)
    ax.text(2.70, 5.45, "Some light is trapped or absorbed;\nsome recombination emits no photon", size=10, color="#7d3745")

    def box(x, y, width, height, text, fill):
        ax.add_patch(FancyBboxPatch((x, y), width, height, boxstyle="round,pad=0.13",
                                   facecolor=fill, edgecolor="#65717b"))
        ax.text(x + width / 2, y + height / 2, text, ha="center", va="center", size=10)

    box(7.6, 5.20, 2.7, 0.62, "Optical collection", "#edf2ff")
    arrow((8.2, 5.05), (8.2, 4.45), "#426cd7")
    box(7.6, 3.60, 2.7, 0.70, "Spectrometer\nread emission spectrum", "#edf2ff")
    ax.plot([10.1, 10.6, 10.6], [5.05, 5.05, 3.05], color="#426cd7", lw=2)
    arrow((10.6, 3.05), (9.6, 2.85), "#426cd7")
    box(7.6, 2.10, 2.7, 0.70, "Calibrated optical power\naccount for collection", "#edf2ff")
    ax.text(7.55, 1.15, "Spectrum → photon energy\nPower + current → photon yield\nPower + IV → energy efficiency", size=11, linespacing=1.7)
    ax.text(0.3, 0.05, "Functional illustration only • no measured spectrum or apparatus model implied", color="#59636e", size=10)
    fig.savefig(Path(__file__).stem + ".png", facecolor="white")
    plt.close(fig)


if __name__ == "__main__":
    main()