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 SinCos(object): funcNames = ('sin', 'cos') filePath = "sc.png" def __init__(self): self.X = np.linspace(0, 4 * np.pi, 200) self.pt = Plotter(1, 2, width=700, height=500, useAgg=True) self.pt.set_xlabel("X") self.pt.use_grid() self.pt.add_annotation(0, "First") self.pt.add_annotation(199, "Last") def __call__(self, frequency): self.pt.set_title("Sin and Cosine: Frequency = {:.2f}x", frequency) with self.pt as p: for funcName in self.funcNames: Y = getattr(np, funcName)(frequency * self.X) p.set_ylabel("{}(X)".format(funcName)) p(self.X, Y) with open(self.filePath, "wb") as fh: self.pt.show(fh=fh)
""" A log plot, with several plots in one subplot, all done in one call to the subplotting tool in context. """ import numpy as np from yampex import Plotter # Construct a Plotter object for a 1000x800 pixel (100 DPI) figure # with a single subplot. pt = Plotter(1, width=10.0, height=8.0) # The plots will be of different bases raised to powers. X = np.linspace(0, 10, 100) pt.set_title("Different Bases Raised to Power 0-10") # The x label will say "Power" and the subplot will have a grid. pt.set_xlabel("Power") pt.use_grid() # Make a subplotting context and work with the single subplot via the # subplot tool sp. It's actually just a reference to pt, but set up # for subplotting. with pt as sp: # Compute the vectors all at once Y2 = np.power(2, X) Y3 = np.power(3, X) Y10 = np.power(10, X) # Just call the subplotting tool with the X-axis vector and all # the Ys at once. sp.semilogy(X, Y2, Y3, Y10, legend=["Base 2", "Base 3", "Base 10"]) # Show the single subplot. pt.show()
L{SpecialAx} object. """ import numpy as np from yampex import Plotter # Construct a Plotter object for a 700x500 pixel (100 DPI) figure with # two subplots. pt = Plotter(1, 2, width=7.0, height=5.0) # The plots, one in each subplot, will be of a sine and cosine with # 200 points from 0 to 4*pi. funcNames = ('sin', 'cos') X = np.linspace(0, 4 * np.pi, 200) pt.set_title("Sine and Cosine") # Each subplot will have an x-axis label of "X" and a grid. pt.set_xlabel("X") pt.use_grid() # Each plot will have an annotation labeled "Last" at its last # point. Note that we can use negative indices referenced to the last # element, just as with Python sequences. pt.add_annotation(-1, "Last") # Make a subplotting context and work with the two subplots via the # subplot tool sp. It's actually just a reference to pt, but set up # for subplotting, with a context for a new subplot each time it's # called. with pt as sp: # Do each plot, sin and then cos. for k, funcName in enumerate(funcNames): if k == 0: # The major ticks are at pi/2 intervals, but only for the
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()