Exemple #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
Exemple #2
0
    def bqplot_data(self,
                    xdata,
                    ydata,
                    *,
                    xheader=None,
                    yheader=None,
                    xlabel=None,
                    ylabel=None,
                    left=None,
                    right=None,
                    ymin=None,
                    ymax=None,
                    legend=True,
                    grid=False,
                    fig=None,
                    latex=True,
                    dpi=150,
                    line_width=1.0,
                    greyscale=False,
                    savefig=None,
                    save_format=None,
                    title=None,
                    **kwargs):
        """
        Plot with ``bqplot``. Experimental and incomplete.
        """

        from bqplot import pyplot as plt
        if not isinstance(ydata, np.ndarray):
            raise TypeError(
                "ydata must be numpy array. Retrieve with `get_values()`.")

        if ydata.ndim == 1:
            ydata = ydata.reshape((-1, 1))

        if fig is None:
            fig = plt.figure(dpi=dpi)
        plt.plot(
            xdata,
            ydata.transpose(),
            linewidth=line_width,
            figure=fig,
        )

        if yheader:
            plt.label(yheader)
        if title:
            plt.title(title)
        plt.show()

        return fig
Exemple #3
0
    def bqplot_data(self,
                    xdata,
                    ydata,
                    xheader=None,
                    yheader=None,
                    xlabel=None,
                    ylabel=None,
                    left=None,
                    right=None,
                    ymin=None,
                    ymax=None,
                    legend=True,
                    grid=False,
                    fig=None,
                    latex=True,
                    dpi=150,
                    greyscale=False,
                    savefig=None,
                    show=True,
                    **kwargs):
        """
        Plot with ``bqplot``. Experimental and imcomplete.
        """

        from bqplot import pyplot as plt
        if not isinstance(ydata, np.ndarray):
            TypeError("ydata must be numpy array. Retrieve with get_values().")

        if ydata.ndim == 1:
            ydata = ydata.reshape((-1, 1))

        plt.figure(dpi=dpi)
        plt.plot(
            xdata,
            ydata.transpose(),
            linewidth=1.5,
        )

        if yheader:
            plt.label(yheader)

        plt.show()
Exemple #4
0
    def plotn(self,
              nrows: int,
              ncols: int,
              yidxes,
              xidxes=None,
              *,
              dpi=DPI,
              titles=None,
              a=None,
              figsize=None,
              xlabel=None,
              ylabel=None,
              sharex=None,
              sharey=None,
              show=True,
              xlabel_offs=(0.5, 0.01),
              ylabel_offs=(0.05, 0.5),
              hspace=0.2,
              wspace=0.2,
              **kwargs):
        """
        Plot multiple subfigures in one figure.

        Parameters ``xidxes``, ``a``, ``xlabels`` and ``ylabels``, if provided,
        must have the same length as ``yidxes``.

        Parameters
        ----------
        nrows : int
            number of rows
        ncols : int
            number of cols
        yidx
            A list of `BaseVar` or index lists.
        """

        nyidxes = len(yidxes)
        if nyidxes > nrows * ncols:
            raise ValueError(
                "yidxes with length %d does not fit nrows=%d and ncols=%d",
                nyidxes, nrows, ncols)

        fig = plt.figure(figsize=figsize, dpi=dpi)

        xidx = (0, )
        aidx = None
        title = ''

        sharex = True if (sharex is None and ncols == 1) else False
        sharey = True if (sharey is None and nrows == 1) else False

        axes = fig.subplots(nrows,
                            ncols,
                            sharex=sharex,
                            sharey=sharey,
                            squeeze=False)

        ii = 0
        for jj in range(nrows):
            for kk in range(ncols):
                if ii >= nyidxes:
                    break

                yidx = yidxes[ii]
                ax = axes[jj, kk]
                if xidxes is not None:
                    xidx = xidxes[ii]

                if a is not None:
                    aidx = a[ii]

                if titles is not None:
                    title = titles[ii]

                fig, ax = self.plot(yidx,
                                    xidx,
                                    a=aidx,
                                    fig=fig,
                                    ax=ax,
                                    xlabel='',
                                    ylabel='',
                                    title=title,
                                    show=False,
                                    **kwargs)
                ii += 1
        if xlabel:
            fig.text(*xlabel_offs, xlabel, ha='center', va='center')
        if ylabel:
            fig.text(*ylabel_offs,
                     ylabel,
                     ha='center',
                     va='center',
                     rotation='vertical')

        fig.subplots_adjust(
            hspace=hspace,
            wspace=wspace,
        )

        if show:
            plt.show()

        return fig, axes
Exemple #5
0
    def plot_data(self,
                  xdata,
                  ydata,
                  *,
                  xheader=None,
                  yheader=None,
                  xlabel=None,
                  ylabel=None,
                  linestyles=None,
                  left=None,
                  right=None,
                  ymin=None,
                  ymax=None,
                  legend=None,
                  grid=False,
                  fig=None,
                  ax=None,
                  latex=True,
                  dpi=DPI,
                  line_width=1.0,
                  font_size=12,
                  greyscale=False,
                  savefig=None,
                  save_format=None,
                  show=True,
                  title=None,
                  hline1=None,
                  hline2=None,
                  vline1=None,
                  hline=None,
                  vline=None,
                  vline2=None,
                  set_xlim=True,
                  set_ylim=True,
                  autoscale=False,
                  figsize=None,
                  legend_bbox=None,
                  legend_loc=None,
                  legend_ncol=1,
                  mask=True,
                  color=None,
                  **kwargs):
        """
        Plot lines for the supplied data and options.

        This functions takes `xdata` and `ydata` values.
        If you provide variable indices instead of values, use `plot()`.

        See the argument lists of `plot()` for more.

        Parameters
        ----------
        xdata : array-like
            An array-like object containing the values for the x-axis variable
        ydata : array
            An array containing the values of each variables for the y-axis variable. The row
            of `ydata` must match the row of `xdata`. Each column correspondings to a variable.
        mask : bool
            If enabled (1), when specifying axis limits, only data in the limits will be
            used for plotting to optimize for autoscaling.
            It is done through an index mask.

        Returns
        -------
        (fig, ax)
            The figure and axis handles

        Examples
        --------
        To plot the results of arithmetic calculation of variables, retrieve the values,
        do the calculation, and plot with `plot_data`.

        >>> v = ss.dae.ts.y[:, ss.PVD1.v.a]
        >>> Ipcmd = ss.dae.ts.y[:, ss.PVD1.Ipcmd_y.a]
        >>> t = ss.dae.ts.t

        >>> ss.TDS.plt.plot_data(t, v * Ipcmd,
        >>>                      xlabel='Time [s]',
        >>>                      ylabel='Ipcmd [pu]')

        """
        mpl.rc('font', family='serif', size=font_size)

        if not isinstance(ydata, np.ndarray):
            raise TypeError(
                "ydata must be a numpy array. Retrieve with get_values().")

        if ydata.ndim == 1:
            ydata = ydata.reshape((-1, 1))

        n_lines = ydata.shape[1]

        if latex:
            set_latex()

        if isinstance(color, (str, float, int)):
            color = [color] * n_lines
        elif color is None:
            color = [None] * n_lines

        # set default x min based on simulation time
        if not left:
            left = xdata[0] - 1e-6
        if not right:
            right = xdata[-1] + 1e-6

        if not linestyles:
            linestyles = ['-', '--', '-.', ':']

        linestyles = linestyles * int(n_lines / len(linestyles) + 1)

        if fig is None or ax is None:
            fig = plt.figure(dpi=dpi, figsize=figsize)
            ax = plt.gca()

        if greyscale:
            plt.gray()

        if mask is True:
            mask = (xdata >= (left - 0.1)) & (xdata <= (right + 0.1))
            xdata = xdata[mask]
            ydata = ydata[mask.reshape(-1, )]

        for i in range(n_lines):
            ax.plot(
                xdata,
                ydata[:, i],
                ls=linestyles[i],
                label=yheader[i] if yheader else None,
                linewidth=line_width,
                color=color[i],
            )

        if xlabel is not None:
            ax.set_xlabel(xlabel)
        elif xheader is not None and len(xheader) > 0:
            ax.set_xlabel(xheader[0])

        if ylabel:
            ax.set_ylabel(ylabel)

        ax.ticklabel_format(useOffset=False)

        if set_xlim is True:
            ax.set_xlim(left=left, right=right)
        if set_ylim is True:
            ax.set_ylim(bottom=ymin, top=ymax)
        if autoscale is True:
            ax.autoscale(axis='y')

        if grid:
            ax.grid(True, linestyle='--')

        if yheader is None:
            legend = False
        elif legend is None:
            if len(yheader) <= 8:
                legend = True

        if legend:
            ax.legend(bbox_to_anchor=legend_bbox,
                      loc=legend_loc,
                      ncol=legend_ncol)

        if title:
            ax.set_title(title)

        # --- process hlines and vlines
        if hline1 or hline2 or vline1 or vline2:
            logger.warning(
                "hline1, hline2, vline1, and vline2 are deprecated. Use `hline` and `vline`."
            )

        if isinstance(hline, (float, int, np.floating, np.integer)):
            hline = [hline]
        elif isinstance(hline, tuple):
            hline = list(hline)
        elif hline is None:
            hline = []

        if isinstance(vline, (float, int, np.floating, np.integer)):
            vline = [vline]
        elif isinstance(vline, tuple):
            vline = list(vline)
        elif vline is None:
            vline = []

        # process the legacy hline1, hline2, and vline1 and vline2
        if hline1:
            hline.append(hline1)
        if hline2:
            hline.append(hline2)
        if vline1:
            vline.append(vline1)
        if vline2:
            vline.append(vline2)

        for loc in hline:
            ax.axhline(y=loc, linewidth=1, ls=':', color='grey')
        for loc in vline:
            ax.axvline(x=loc, linewidth=1, ls=':', color='grey')

        # --- hline and vline finished ---

        plt.draw()

        if savefig:
            if save_format is None:
                save_format = 'png'

            if dpi is None:
                dpi = 200
            else:
                dpi = max(dpi, 200)

            # use supplied file name
            if isinstance(savefig, str):
                outfile = savefig + '.' + save_format
            # or generate a new name
            else:
                count = 1
                while True:
                    outfile = f'{self.file_name}_{count}.{save_format}'
                    if not os.path.isfile(outfile):
                        break
                    count += 1

            fig.savefig(outfile, dpi=dpi, bbox_inches='tight')
            logger.info('Figure saved to "%s".', outfile)

        if show:
            plt.show()

        return fig, ax
Exemple #6
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
Exemple #7
0
    def plot_data(self,
                  xdata,
                  ydata,
                  xheader=None,
                  yheader=None,
                  xlabel=None,
                  ylabel=None,
                  line_styles=None,
                  left=None,
                  right=None,
                  ymin=None,
                  ymax=None,
                  legend=True,
                  grid=False,
                  fig=None,
                  ax=None,
                  latex=True,
                  dpi=100,
                  greyscale=False,
                  savefig=None,
                  show=True,
                  **kwargs):
        """
        Plot lines for the supplied data and options. This functions takes `xdata` and `ydata` values. If
        you provide variable indices instead of values, use `plot()`.

        Parameters
        ----------
        xdata : array-like
            An array-like object containing the values for the x-axis variable

        ydata : array
            An array containing the values of each variables for the y-axis variable. The row
            of `ydata` must match the row of `xdata`. Each column correspondings to a variable.

        xheader : list
            A list containing the variable names for the x-axis variable

        yheader : list
            A list containing the variable names for the y-axis variable

        xlabel : str
            A label for the x axis

        ylabel : str
            A label for the y axis

        left : float
            The starting value of the x axis

        right : float
            The ending value of the x axis

        ymin : float
            The minimum value of the y axis
        ymax : float
            The maximum value of the y axis

        legend : bool
            True to show legend and False otherwise
        grid : bool
            True to show grid and False otherwise
        fig
            Matplotlib fig object to draw the axis on
        ax
            Matplotlib axis object to draw the lines on
        latex : bool
            True to enable latex and False to disable

        dpi : int
            Dots per inch for screen print or save
        greyscale : bool
            True to use greyscale, False otherwise
        savefig : bool
            True to save to png figure file
        show : bool
            True to show the image

        kwargs
            Optional kwargs

        Returns
        -------
        (fig, ax)
            The figure and axis handles
        """

        if not isinstance(ydata, np.ndarray):
            TypeError("ydata must be numpy array. Retrieve with get_values().")

        if ydata.ndim == 1:
            ydata = ydata.reshape((-1, 1))

        n_lines = ydata.shape[1]

        mpl.rc('font', family='Arial', size=12)

        using_latex = set_latex(latex)

        # set default x min based on simulation time
        if not left:
            left = xdata[0] - 1e-6
        if not right:
            right = xdata[-1] + 1e-6

        if not line_styles:
            line_styles = ['-', '--', '-.', ':']
        line_styles = line_styles * int(len(ydata) / len(line_styles) + 1)

        if not (fig and ax):
            fig = plt.figure(dpi=dpi)
            ax = plt.gca()

        if greyscale:
            plt.gray()

        for i in range(n_lines):
            ax.plot(
                xdata,
                ydata[:, i],
                ls=line_styles[i],
                label=yheader[i] if yheader else None,
                linewidth=1,
                color='0.2' if greyscale else None,
            )

        if xlabel:
            if using_latex:
                ax.set_xlabel(label_texify(xlabel))
        else:
            ax.set_xlabel(xheader[0])

        if ylabel:
            if using_latex:
                ax.set_ylabel(label_texify(ylabel))
            else:
                ax.set_ylabel(ylabel)

        ax.ticklabel_format(useOffset=False)
        ax.set_xlim(left=left, right=right)
        ax.set_ylim(ymin=ymin, ymax=ymax)

        if grid:
            ax.grid(b=True, linestyle='--')

        if legend:
            if yheader:
                ax.legend()

        plt.draw()

        if savefig:
            count = 1

            while True:
                outfile = self.file_name + '_' + str(count) + '.png'
                if not os.path.isfile(outfile):
                    break
                count += 1

            try:
                fig.savefig(outfile, dpi=dpi)
                logger.info(f'Figure saved to <{outfile}>')
            except IOError:
                logger.error(
                    '* An unknown error occurred. Try disabling LaTeX with "-d".'
                )
                return

        if show:
            plt.show()

        return fig, ax
Exemple #8
0
    def plot_data(self,
                  xdata,
                  ydata,
                  xheader=None,
                  yheader=None,
                  xlabel=None,
                  ylabel=None,
                  line_styles=None,
                  left=None,
                  right=None,
                  ymin=None,
                  ymax=None,
                  legend=None,
                  grid=False,
                  fig=None,
                  ax=None,
                  latex=True,
                  dpi=150,
                  line_width=1.0,
                  font_size=12,
                  greyscale=False,
                  savefig=None,
                  save_format=None,
                  show=True,
                  title=None,
                  **kwargs):
        """
        Plot lines for the supplied data and options. This functions takes `xdata` and `ydata` values. If
        you provide variable indices instead of values, use `plot()`.

        Parameters
        ----------
        xdata : array-like
            An array-like object containing the values for the x-axis variable

        ydata : array
            An array containing the values of each variables for the y-axis variable. The row
            of `ydata` must match the row of `xdata`. Each column correspondings to a variable.

        xheader : list
            A list containing the variable names for the x-axis variable

        yheader : list
            A list containing the variable names for the y-axis variable

        xlabel : str
            Text label for the x axis

        ylabel : str
            Text label for the y axis

        left : float
            The starting value of the x axis

        right : float
            The ending value of the x axis

        ymin : float
            The minimum value of the y axis
        ymax : float
            The maximum value of the y axis

        legend : bool
            True to show legend and False otherwise
        grid : bool
            True to show grid and False otherwise
        fig
            Matplotlib fig object to draw the axis on
        ax
            Matplotlib axis object to draw the lines on
        latex : bool
            True to enable latex and False to disable
        greyscale : bool
            True to use greyscale, False otherwise
        savefig : bool
            True to save to png figure file
        save_format : str
            File extension string (pdf, png or jpg) for the savefig format
        dpi : int
            Dots per inch for screen print or save. savefig uses a minimum of 200 dpi
        line_width : float
            Plot line width
        font_size : float
            Text font size (labels and legends)
        show : bool
            True to show the image
        kwargs
            Optional kwargs

        Returns
        -------
        (fig, ax)
            The figure and axis handles
        """
        mpl.rc('font', family='Arial', size=font_size)

        if not isinstance(ydata, np.ndarray):
            TypeError(
                "ydata must be a numpy array. Retrieve with get_values().")

        if ydata.ndim == 1:
            ydata = ydata.reshape((-1, 1))

        n_lines = ydata.shape[1]

        set_latex(latex)

        # set default x min based on simulation time
        if not left:
            left = xdata[0] - 1e-6
        if not right:
            right = xdata[-1] + 1e-6

        if not line_styles:
            line_styles = ['-', '--', '-.', ':']
        line_styles = line_styles * int(len(ydata) / len(line_styles) + 1)

        hold = True
        if not (fig and ax):
            fig = plt.figure(dpi=dpi)
            ax = plt.gca()
            hold = False

        if greyscale:
            plt.gray()

        for i in range(n_lines):
            ax.plot(
                xdata,
                ydata[:, i],
                ls=line_styles[i],
                label=yheader[i] if yheader else None,
                linewidth=line_width,
                color='0.2' if greyscale else None,
            )

        if xlabel is not None:
            ax.set_xlabel(xlabel)
        else:
            ax.set_xlabel(xheader[0])

        if ylabel:
            ax.set_ylabel(ylabel)

        ax.ticklabel_format(useOffset=False)

        if not hold:
            ax.set_xlim(left=left, right=right)
            ax.set_ylim(bottom=ymin, top=ymax)
        else:
            ax.autoscale(axis='y')

        if grid:
            ax.grid(b=True, linestyle='--')

        if yheader is None:
            legend = False
        elif legend is None:
            if len(yheader) <= 8:
                legend = True

        if legend:
            ax.legend()

        if title:
            ax.set_title(title)

        plt.draw()

        if savefig:
            if save_format is None:
                save_format = 'png'

            if dpi is None:
                dpi = 200
            else:
                dpi = max(dpi, 200)

            count = 1
            while True:
                outfile = f'{self.file_name}_{count}.{save_format}'
                if not os.path.isfile(outfile):
                    break
                count += 1

            fig.savefig(outfile, dpi=dpi)
            logger.info(f'Figure saved to "{outfile}".')

        if show:
            plt.show()

        return fig, ax
Exemple #9
0
    def plot_data(self,
                  xdata,
                  ydata,
                  *,
                  xheader=None,
                  yheader=None,
                  xlabel=None,
                  ylabel=None,
                  linestyles=None,
                  left=None,
                  right=None,
                  ymin=None,
                  ymax=None,
                  legend=None,
                  grid=False,
                  fig=None,
                  ax=None,
                  latex=True,
                  dpi=150,
                  line_width=1.0,
                  font_size=12,
                  greyscale=False,
                  savefig=None,
                  save_format=None,
                  show=True,
                  title=None,
                  hline1=None,
                  hline2=None,
                  vline1=None,
                  vline2=None,
                  set_xlim=True,
                  set_ylim=True,
                  autoscale=False,
                  legend_bbox=None,
                  legend_loc=None,
                  **kwargs):
        """
        Plot lines for the supplied data and options.

        This functions takes `xdata` and `ydata` values.
        If you provide variable indices instead of values, use `plot()`.

        See the argument lists of `plot()` for more.

        Parameters
        ----------
        xdata : array-like
            An array-like object containing the values for the x-axis variable
        ydata : array
            An array containing the values of each variables for the y-axis variable. The row
            of `ydata` must match the row of `xdata`. Each column correspondings to a variable.

        Returns
        -------
        (fig, ax)
            The figure and axis handles

        Examples
        --------
        To plot the results of arithmetic calculation of variables, retrieve the values,
        do the calculation, and plot with `plot_data`.

        >>> v = ss.dae.ts.y[:, ss.PVD1.v.a]
        >>> Ipcmd = ss.dae.ts.y[:, ss.PVD1.Ipcmd_y.a]
        >>> t = ss.dae.ts.t

        >>> ss.TDS.plt.plot_data(t, v * Ipcmd,
        >>>                      xlabel='Time [s]',
        >>>                      ylabel='Ipcmd [pu]')

        """
        mpl.rc('font', family='serif', size=font_size)

        if not isinstance(ydata, np.ndarray):
            raise TypeError(
                "ydata must be a numpy array. Retrieve with get_values().")

        if ydata.ndim == 1:
            ydata = ydata.reshape((-1, 1))

        n_lines = ydata.shape[1]

        if latex:
            set_latex()

        # set default x min based on simulation time
        if not left:
            left = xdata[0] - 1e-6
        if not right:
            right = xdata[-1] + 1e-6

        if not linestyles:
            linestyles = ['-', '--', '-.', ':']

        linestyles = linestyles * int(n_lines / len(linestyles) + 1)

        if fig is None or ax is None:
            fig = plt.figure(dpi=dpi)
            ax = plt.gca()

        if greyscale:
            plt.gray()

        for i in range(n_lines):
            ax.plot(
                xdata,
                ydata[:, i],
                ls=linestyles[i],
                label=yheader[i] if yheader else None,
                linewidth=line_width,
                color='0.2' if greyscale else None,
            )

        if xlabel is not None:
            ax.set_xlabel(xlabel)
        elif xheader is not None and len(xheader) > 0:
            ax.set_xlabel(xheader[0])

        if ylabel:
            ax.set_ylabel(ylabel)

        ax.ticklabel_format(useOffset=False)

        if set_xlim is True:
            ax.set_xlim(left=left, right=right)
        if set_ylim is True:
            ax.set_ylim(bottom=ymin, top=ymax)
        if autoscale is True:
            ax.autoscale(axis='y')

        if grid:
            ax.grid(b=True, linestyle='--')

        if yheader is None:
            legend = False
        elif legend is None:
            if len(yheader) <= 8:
                legend = True

        if legend:
            ax.legend(bbox_to_anchor=legend_bbox, loc=legend_loc)

        if title:
            ax.set_title(title)

        if hline1:
            ax.axhline(y=hline1, linewidth=1, ls=':', color='grey')
        if hline2:
            ax.axhline(y=hline2, linewidth=1, ls=':', color='grey')
        if vline1:
            ax.axvline(x=vline1, linewidth=1, ls=':', color='grey')
        if vline2:
            ax.axvline(x=vline2, linewidth=1, ls=':', color='grey')

        plt.draw()

        if savefig:
            if save_format is None:
                save_format = 'png'

            if dpi is None:
                dpi = 200
            else:
                dpi = max(dpi, 200)

            count = 1
            while True:
                outfile = f'{self.file_name}_{count}.{save_format}'
                if not os.path.isfile(outfile):
                    break
                count += 1

            fig.savefig(outfile, dpi=dpi)
            logger.info('Figure saved to "%s".', outfile)

        if show:
            plt.show()

        return fig, ax
Exemple #10
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=DPI,
             figsize=None,
             base_color='black',
             show=True,
             latex=True,
             style='default'):
        """
        Plot utility for eigenvalues in the S domain.

        Parameters
        ----------
        mu : array, optional
            an array of complex eigenvalues
        fig : figure handl, optional
            existing matplotlib figure handle
        ax : axis handle, optional
            existing axis handle
        left : int, optional
            left tick for the x-axis, by default -6
        right : float, optional
            right tick, by default 0.5
        ymin : int, optional
            bottom tick, by default -8
        ymax : int, optional
            top tick, by default 8
        damping : float, optional
            damping value for which the dash plots are drawn
        line_width : float, optional
            default line width, by default 0.5
        dpi : int, optional
            figure dpi
        figsize : [type], optional
            default figure size, by default None
        base_color : str, optional
            base color for negative eigenvalues
        show : bool, optional
            True to show figure after plot, by default True
        latex : bool, optional
            True to use latex, by default True

        Returns
        -------
        figure
            matplotlib figure object
        axis
            matplotlib axis object

        """

        set_style(style)

        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 abs(re) <= self.config.tol:
                z_mu_real.append(re)
                z_mu_imag.append(im)
            elif re > self.config.tol:
                p_mu_real.append(re)
                p_mu_imag.append(im)
            elif re < -self.config.tol:
                n_mu_real.append(re)
                n_mu_imag.append(im)

        if latex:
            set_latex()

        if fig is None or ax is None:
            fig = plt.figure(dpi=dpi, figsize=figsize)
            ax = plt.gca()

        ax.scatter(z_mu_real,
                   z_mu_imag,
                   marker='o',
                   s=40,
                   linewidth=0.5,
                   facecolors='none',
                   edgecolors='green')
        ax.scatter(n_mu_real,
                   n_mu_imag,
                   marker='x',
                   s=40,
                   linewidth=0.5,
                   color=base_color)
        ax.scatter(p_mu_real,
                   p_mu_imag,
                   marker='x',
                   s=40,
                   linewidth=0.5,
                   color='red')

        # axes lines
        ax.axhline(linewidth=0.5, color='grey', linestyle='--')
        ax.axvline(linewidth=0.5, color='grey', linestyle='--')

        # TODO: Improve the damping and range
        # --- 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='--')
        # --- damping lines end ---

        if latex:
            ax.set_xlabel('Real [$s^{-1}$]')
            ax.set_ylabel('Imaginary [$s^{-1}$]')
        else:
            ax.set_xlabel('Real [s -1]')
            ax.set_ylabel('Imaginary [s -1]')

        ax.set_xlim(left=left, right=right)
        ax.set_ylim(ymin, ymax)

        if show is True:
            plt.show()
        return fig, ax