def plot_model_fit_overview(f_i, z_i, model): #Generate plot data from fitted model z_fit = model.predict(f_i) fig = plt.figure(constrained_layout=True, figsize=(12, 5)) gs = fig.add_gridspec(2, 2) f_ax1 = fig.add_subplot(gs[:, 0]) f_ax1.set_title("Nyquist plot") f_ax2 = fig.add_subplot(gs[0, 1]) f_ax2.set_title("Bode plot") f_ax3 = fig.add_subplot(gs[1, 1]) plot_nyquist(f_ax1, z_i, fmt='o') plot_nyquist(f_ax1, z_fit, fmt='-') plot_bode((f_ax2, f_ax3), f_i, z_i, ls='', marker='s', label='Data') plot_bode((f_ax2, f_ax3), f_i, z_fit, ls='-', marker='', label='Fit') f_ax2.legend() return gs
def test_plot_bode(): f = [1, 10, 100] Z = np.array([1, 2, 3]) + 1j*np.array([2, 3, 4]) _, axes = plt.subplots(nrows=2) axes = plot_bode(axes, f, Z, scale=10) xs, ys = axes[0].lines[0].get_xydata().T assert (xs == f).all() and (ys == np.abs(Z)).all() xs, ys = axes[1].lines[0].get_xydata().T assert (xs == f).all() and (ys == -np.angle(Z, deg=True)).all()
def plot(self, ax=None, f_data=None, Z_data=None, kind='altair', **kwargs): """ visualizes the model and optional data as a nyquist, bode, or altair (interactive) plots Parameters ---------- ax: matplotlib.axes axes to plot on f_data: np.array of type float Frequencies of input data (for Bode plots) Z_data: np.array of type complex Impedance data to plot kind: {'altair', 'nyquist', 'bode'} type of plot to visualize Other Parameters ---------------- **kwargs : optional If kind is 'nyquist' or 'bode', used to specify additional `matplotlib.pyplot.Line2D` properties like linewidth, line color, marker color, and labels. If kind is 'altair', used to specify nyquist height as `size` Returns ------- ax: matplotlib.axes axes of the created nyquist plot """ if kind == 'nyquist': if ax is None: fig, ax = plt.subplots(figsize=(5, 5)) if Z_data is not None: ax = plot_nyquist(ax, Z_data, ls='', marker='s', **kwargs) if self._is_fit(): if f_data is not None: f_pred = f_data else: f_pred = np.logspace(5, -3) Z_fit = self.predict(f_pred) ax = plot_nyquist(ax, Z_fit, ls='-', marker='', **kwargs) return ax elif kind == 'bode': if ax is None: fig, ax = plt.subplots(nrows=2, figsize=(5, 5)) if f_data is not None: f_pred = f_data else: f_pred = np.logspace(5, -3) if Z_data is not None: if f_data is None: raise ValueError('f_data must be specified if' + ' Z_data for a Bode plot') ax = plot_bode(ax, f_data, Z_data, ls='', marker='s', **kwargs) if self._is_fit(): Z_fit = self.predict(f_pred) ax = plot_bode(ax, f_pred, Z_fit, ls='-', marker='', **kwargs) return ax elif kind == 'altair': plot_dict = {} if Z_data is not None and f_data is not None: plot_dict['data'] = {'f': f_data, 'Z': Z_data} if self._is_fit(): if f_data is not None: f_pred = f_data else: f_pred = np.logspace(5, -3) Z_fit = self.predict(f_pred) if self.name is not None: name = self.name else: name = 'fit' plot_dict[name] = {'f': f_pred, 'Z': Z_fit, 'fmt': '-'} chart = plot_altair(plot_dict, **kwargs) return chart else: raise ValueError("Kind must be one of 'altair'," + f"'nyquist', or 'bode' (received {kind})")