Пример #1
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
Пример #2
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
Пример #3
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
Пример #4
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
Пример #5
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