class CurvePlotter(object): """ I do the plotting. """ N = 100 width = 1400 height = 1400 Vgs = [0.0, 10.0] def __init__(self): """ Constructs a Yampex Plotter object for a figure with two subplots. """ self.mList = [] # Small MOSFET in an IC self.mList.append(MOSFET(2.5e-9, 5e17)) # High-current Power MOSFET self.mList.append(MOSFET(4e-9, 2.7e19)) # Plotter self.N_sp = len(self.mList) self.pt = Plotter(self.N_sp, width=self.width, height=self.height) self.pt.use_grid() self.pt.set_xlabel("Vgst") self.pt.set_ylabel("Vdsp") self.pt.add_legend("Vgst/n") self.pt.add_legend("(Vgst-f(x))/n") self.pt.use_labels() def Vdsp_1(self, m, Vgs): Vgst = Vgs - m.VT return Vgst / m.n(Vgs) def Vdsp_2(self, m, Vgs, x=0.1): Vgst = Vgs - m.VT n = m.n(Vgs) Pt = m.Pt second = 2 * n * Pt * np.log((1 + np.exp(Vgst / (2 * n * Pt)))**np.sqrt(x) - 1) return (Vgst - second) / n def plot(self): """ """ with self.pt as sp: for m in self.mList: sp.set_title("Vdsp vs Vgst, computed both ways, for {}", m) Vgs = np.linspace(self.Vgs[0], self.Vgs[1], 100) #sp(Vgs, self.Vdsp_1(m, Vgs), self.Vdsp_2(m, Vgs)) sp(Vgs, self.Vdsp_2(m, Vgs)) self.pt.show()
class CurvePlotter(object): """ I do the plotting. """ width = 1400 height = 1200 N = 200 def __init__(self): """ Constructs a Yampex Plotter object for a figure with one subplot. """ self.pt = Plotter(1, width=self.width, height=self.height) self.pt.use_grid() def eta(self, Vds, smooth=False): if smooth: eta = 0.05 * np.log(1 + np.exp(20 * (1 - Vds))) else: eta = np.clip(1 - Vds, 0, None) return eta def Cdg(self, eta): """ The function for Cdg:: Cdg = W*L*Cdox*(4+28*eta+22*eta^2+6*eta^3)/(15*(1+eta)^3) """ result = 4 + 28 * eta + 22 * eta**2 + 6 * eta**3 return result / (15 * (1 + eta)**3) def plot(self): """ Plots the curve for Cdg vs Vds, given Vds_prime = 1. """ self.pt.set_ylabel("Cdg") with self.pt as sp: sp.set_title("Cdg vs Vds") sp.set_xlabel("Vds") Vds = np.linspace(0, 2, self.N) eta = self.eta(Vds, True) Cdg = self.Cdg(eta) ax = sp(Vds, eta, Cdg) self.pt.show()
class CurvePlotter(object): """ I do the plotting. """ width = 1400 height = 1400 N = 100 gamma = [0.5, 1.0, 2.5] Vgs = [0.0, 10.0] def __init__(self): """ Constructs a Yampex Plotter object for a figure with two subplots. """ self.pt = Plotter(2, width=self.width, height=self.height) self.pt.use_grid() def n(self, gamma, Vgs, Tj=25): """ The function for n: M{n = 1+gamma/(-gamma+2*sqrt(gamma^2/4 + Vgs + 1.10/300*(Tj+273.15)))} """ T = Tj + 273.15 n = gamma.copy() # Otherwise we wind up modifying gamma n /= -gamma + 2 * np.sqrt(gamma**2 / 4 + Vgs + 1.1 / 300 * T) n += 1 return n def subplot(self, sp, X, aVals, bVals, semilog=False): """ Given the subplotting tool I{sp} and the supplied 1-D Numpy array of I{X} values, plots the curves for each combination of I{a} in I{aVals} and I{b} in I{bVals}. """ Ys = [] for a, b in zip(aVals, bVals): Ys.append(self.func(X, a, b)) sp.add_legend("a={:.2f}, b={:.2f}", a, b) if semilog: sp.semilogy(X, *Ys) else: sp(X, *Ys) def plot(self): """ Plots the curves for each combination of I{a} in I{aVals} and its corresponding I{b} in I{bVals}, from my I{xMin} to my I{xMax} and from zero to double my I{xMax}. """ self.pt.set_ylabel("n") with self.pt as sp: sp.set_title("n vs gamma with stepped Vgs") sp.set_xlabel("gamma") ax = sp() gamma = np.linspace(self.gamma[0], self.gamma[1], self.N) for Vgs in np.linspace(self.Vgs[0], self.Vgs[1], 5): with sp.prevOpts(): sp.add_legend("Vgs: {:.1f}", Vgs) n = self.n(gamma, Vgs) ax.plot(gamma, n) sp.set_title("n vs Vgs with stepped gamma") sp.set_xlabel("Vgs") ax = sp() Vgs = np.linspace(self.Vgs[0], self.Vgs[1], self.N) for gamma in np.linspace(self.gamma[0], self.gamma[1], 5): with sp.prevOpts(): sp.add_legend("gamma: {:.1f}", gamma) n = self.n(gamma, Vgs) ax.plot(Vgs, n) self.pt.show()
class CurvePlotter(object): """ I do the plotting. """ width = 1400 height = 1200 xMin, xMax = 5.0, 8.0 N = 100 def __init__(self): """ Constructs a Yampex Plotter object for a figure with two subplots. """ self.pt = Plotter(2, width=self.width, height=self.height) self.pt.use_grid() self.pt.set_title("Exponentials plotted from {:.1f} to {:.1f}", self.xMin, self.xMax) self.pt.set_xlabel("X") self.pt.set_ylabel("a*exp(-b*X)") def func(self, X, a, b): """ The exponential function M{a*exp(-b*X)} """ return a * np.exp(-b * X) def leastDiff(self, Ys, logspace=False): """ Returns the index of the vectors of I{Ys} where there is the least difference between their values. Set I{logspace} C{True} to have the difference calculated in logspace, for a semilog plot. """ Z = np.row_stack(Ys) if logspace: Z = np.log(Z) V = np.var(Z, axis=0) return np.argmin(V) def subplot(self, sp, X, aVals, bVals, semilog=False): """ Given the subplotting tool I{sp} and the supplied 1-D Numpy array of I{X} values, plots the curves for each combination of I{a} in I{aVals} and I{b} in I{bVals}. Returns the value of I{X} where there is the least difference between the curves. """ Ys = [] for a, b in zip(aVals, bVals): Ys.append(self.func(X, a, b)) sp.add_legend("a={:.2f}, b={:.2f}", a, b) k = self.leastDiff(Ys, semilog) sp.add_annotation(k, X[k]) if semilog: sp.semilogy(X, *Ys) else: sp(X, *Ys) def plot(self, aVals, bVals): """ Plots the curves for each combination of I{a} in I{aVals} and its corresponding I{b} in I{bVals}, from my I{xMin} to my I{xMax} and from zero to double my I{xMax}. """ with self.pt as sp: # Top subplot: The range of interest X = np.linspace(self.xMin, self.xMax, self.N) self.subplot(sp, X, aVals, bVals) # Bottom subplot: Positive X surrounding the range of # interest X = np.linspace(0, 2 * self.xMax, self.N) sp.add_axvline(self.xMin) sp.add_axvline(self.xMax) self.subplot(sp, X, aVals, bVals, semilog=True) self.pt.show()