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
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
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
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
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