def plot(self, left=-6, right=0.5, ymin=-8, ymax=8, damping=0.05, linewidth=0.5, dpi=150): mpl.rc('font', family='Times New Roman', size=12) mu_real = self.mu.real() mu_imag = self.mu.imag() p_mu_real, p_mu_imag = list(), list() z_mu_real, z_mu_imag = list(), list() n_mu_real, n_mu_imag = list(), list() for re, im in zip(mu_real, mu_imag): if re == 0: z_mu_real.append(re) z_mu_imag.append(im) elif re > 0: p_mu_real.append(re) p_mu_imag.append(im) elif re < 0: n_mu_real.append(re) n_mu_imag.append(im) if len(p_mu_real) > 0: logger.warning( 'System is not stable due to {} positive eigenvalues.'.format( len(p_mu_real))) else: logger.info( 'System is small-signal stable in the initial neighbourhood.') mpl.rc('text', usetex=True) fig, ax = plt.subplots(dpi=dpi) ax.scatter(n_mu_real, n_mu_imag, marker='x', s=40, linewidth=0.5, color='black') ax.scatter(z_mu_real, z_mu_imag, marker='o', s=40, linewidth=0.5, facecolors='none', edgecolors='black') ax.scatter(p_mu_real, p_mu_imag, marker='x', s=40, linewidth=0.5, color='black') ax.axhline(linewidth=0.5, color='grey', linestyle='--') ax.axvline(linewidth=0.5, color='grey', linestyle='--') # plot 5% damping lines xin = np.arange(left, 0, 0.01) yneg = xin / damping ypos = - xin / damping ax.plot(xin, yneg, color='grey', linewidth=linewidth, linestyle='--') ax.plot(xin, ypos, color='grey', linewidth=linewidth, linestyle='--') ax.set_xlabel('Real') ax.set_ylabel('Imaginary') ax.set_xlim(left=left, right=right) ax.set_ylim(ymin, ymax) plt.show() return fig, ax
def panoview(self, mdl, *, ncols=3, vars=None, idx=None, a=None, figsize=None, **kwargs): """ Panoramic view of variables of a given model instance. Select variables through ``vars``. Select devices through ``idx`` or ``a``, which has a higher priority. This function also takes other arguments recognizable by ``self.plot``. Parameters ---------- mdl : ModelBase Model instance ncol : int Number of columns var : list of str A list of variable names to display idx : list A list of device idx-es for showing a : list of int A list of device 0-based positions for showing figsize : tuple Figure size for plotting Examples -------- To plot ``omega`` and ``delta`` of GENROUs ``GENROU_1`` and ``GENROU_2``: .. code-block :: python system.TDS.plt.plot(system.GENROU, vars=['omega', 'delta'], idx=['GENROU_1', 'GENROU_2']) """ # `a` takes precedece over `idx` if a is None: a = mdl.idx2uid(idx) # compute the number of rows and cols states = list() algebs = list() states_and_ext = mdl.cache.states_and_ext algebs_and_ext = mdl.cache.algebs_and_ext if vars is None: states = states_and_ext.values() algebs = algebs_and_ext.values() else: for item in vars: if item in states_and_ext: states.append(states_and_ext[item]) elif item in algebs_and_ext: algebs.append(algebs_and_ext[item]) else: logger.warning( "Variable <%s> does not exist in model <%s>", item, mdl.class_name) nstates = len(states) nalgebs = len(algebs) nrows_states = math.ceil(nstates / ncols) nrows_algebs = math.ceil(nalgebs / ncols) # build canvas if figsize is None: figsize = (3 * ncols, 2 * (nrows_states + nrows_algebs)) fig, axes = plt.subplots( nrows_states + nrows_algebs, ncols, figsize=figsize, dpi=DPI, squeeze=False, ) fig.tight_layout() # turn off unused axes if nstates % ncols != 0: for i in range(nstates % ncols, ncols): axes[nrows_states - 1, i].axis('off') if nalgebs % ncols != 0: for i in range(nalgebs % ncols, ncols): axes[-1, i].axis('off') # plot states for ii, item in enumerate(states): row_no = math.floor(ii / ncols) col_no = ii % ncols self.plot(item, a=a, title=f'${item.tex_name}$', xlabel='', fig=fig, ax=axes[row_no, col_no], show=False, **kwargs) # plot algebs for ii, item in enumerate(algebs): row_no = math.floor(ii / ncols) + nrows_states col_no = ii % ncols self.plot(item, a=a, title=f'${item.tex_name}$', xlabel='', fig=fig, ax=axes[row_no, col_no], show=False, **kwargs) return fig, axes
def plot(self, mu=None, fig=None, ax=None, left=-6, right=0.5, ymin=-8, ymax=8, damping=0.05, line_width=0.5, dpi=150, show=True, latex=True): """ Plot utility for eigenvalues in the S domain. """ mpl.rc('font', family='Times New Roman', size=12) if mu is None: mu = self.mu mu_real = mu.real() mu_imag = mu.imag() p_mu_real, p_mu_imag = list(), list() z_mu_real, z_mu_imag = list(), list() n_mu_real, n_mu_imag = list(), list() for re, im in zip(mu_real, mu_imag): if re == 0: z_mu_real.append(re) z_mu_imag.append(im) elif re > 0: p_mu_real.append(re) p_mu_imag.append(im) elif re < 0: n_mu_real.append(re) n_mu_imag.append(im) if len(p_mu_real) > 0: logger.warning( 'System is not stable due to %d positive eigenvalues.', len(p_mu_real)) else: logger.info( 'System is small-signal stable in the initial neighborhood.') if latex: set_latex() if fig is None or ax is None: fig, ax = plt.subplots(dpi=dpi) ax.scatter(n_mu_real, n_mu_imag, marker='x', s=40, linewidth=0.5, color='black') ax.scatter(z_mu_real, z_mu_imag, marker='o', s=40, linewidth=0.5, facecolors='none', edgecolors='black') ax.scatter(p_mu_real, p_mu_imag, marker='x', s=40, linewidth=0.5, color='black') ax.axhline(linewidth=0.5, color='grey', linestyle='--') ax.axvline(linewidth=0.5, color='grey', linestyle='--') # plot 5% damping lines xin = np.arange(left, 0, 0.01) yneg = xin / damping ypos = -xin / damping ax.plot(xin, yneg, color='grey', linewidth=line_width, linestyle='--') ax.plot(xin, ypos, color='grey', linewidth=line_width, linestyle='--') ax.set_xlabel('Real') ax.set_ylabel('Imaginary') ax.set_xlim(left=left, right=right) ax.set_ylim(ymin, ymax) if show is True: plt.show() return fig, ax