Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    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