def plot_astrometric_residuals(ax: matplotlib.axes.Axes, xs: np.ndarray, ys: np.ndarray) -> None: """ Plot the astrometric residual field of a set of points. Parameters ---------- ax: Matplotlib axis in which to plot xs: Array of the x- and y-components of the field ys: Array of the x- and y-components of the astrometric residual field Returns ------- None """ qdict = dict( alpha=1, angles='uv', headlength=5, headwidth=3, headaxislength=4, minlength=0, pivot='middle', scale_units='xy', width=0.002, color='#001146' ) q = ax.quiver(xs[:, 0], xs[:, 1], ys[:, 0], ys[:, 1], scale=1, **qdict) ax.quiverkey(q, 0.0, 1.8, 0.1, 'residual = 0.1 arcsec', coordinates='data', labelpos='N', color='darkred', labelcolor='darkred') ax.set_xlabel('RA [degrees]') ax.set_ylabel('Dec [degrees]') ax.set_xlim(-1.95, 1.95) ax.set_ylim(-1.9, 2.0) ax.set_aspect('equal')
def plot( self, xlabel: str = "Method difference", ylabel: str = "Folded CDF (%)", label: str = "$M_1$ - $M_2$", unit: str = None, title: str = None, color: str = "blue", legend: bool = True, square: bool = False, show_hline: bool = True, show_vlines: bool = True, show_markers: bool = True, ax: matplotlib.axes.Axes = None, ) -> matplotlib.axes.Axes: """Plot mountain plot Parameters ---------- xlabel : str, optional The label which is added to the X-axis. (default: "Method difference") ylabel : str, optional The label which is added to the Y-axis. (default: "Folded CDF (%)") label : str, optional mountaint line legend label (default:"Method 1 - Method 2" ) unit : str, optional unit to disply for x-axis title : str, optional figure title, if none there will be no title (default: None) legend : bool, optional If True, will provide a legend containing the computed regression equation. (default: True) square : bool, optional If True, set the Axes aspect to "equal" so each cell will be square-shaped. (default: True) color : str, optional Color for mountain plot elements show_hline: bool, optional If set show horizontal lines for iqr show_vlines: bool, optional If set show vertical lines at iqr and median show_markers: bool, optional If set show markers at iqr and median ax : matplotlib.axes.Axes, optional matplotlib axis object, if not passed, uses gca() Returns ------- matplotlib.axes.Axes axes object with the plot """ ax = ax or plt.gca() ax.step( y=self.result["mountain"], x=self.result["quantile"], where="mid", label=f"{label} AUC={self.result['auc']:.2f}", color=color, ) if show_hline: ax.hlines( self.result["mountain_iqr"], xmin=self.result["iqr"][0], xmax=self.result["iqr"][1], color=color, ) if show_vlines: ax.vlines( self.result["median"], ymin=0, ymax=50, label=f"median={self.result['median']:.2f} {unit or ''}", linestyle="--", color=color, ) if self.iqr > 0: ax.vlines( self.result["iqr"], ymin=0, ymax=50 - self.iqr / 2, label=( f"{self.iqr:.2f}% IQR =" f"{self.result['iqr'][1] - self.result['iqr'][0]:.2f}" "{unit or ''}"), linestyle=":", color=color, ) if show_markers: ax.plot( self.result["median"], self.result["mountain_median"], "o", color=color, ) if self.iqr > 0: ax.plot( self.result["iqr"], self.result["mountain_iqr"], "o", color=color, ) u = f"({unit})" if unit else "" ax.set(xlabel=f"{xlabel} {u}", ylabel=ylabel or None, title=title or None) ax.legend(loc="upper left", fontsize="medium") if legend: ax.legend(loc="upper left", frameon=False) if square: ax.set_aspect("equal") return ax
def plot( self, x_label: str = "Method 1", y_label: str = "Method 2", title: str = None, line_reference: bool = True, line_CI: bool = True, legend: bool = True, square: bool = False, ax: matplotlib.axes.Axes = None, point_kws: Optional[Dict] = None, color_regr: Optional[str] = None, alpha_regr: Optional[float] = None, ) -> matplotlib.axes.Axes: """Plot regression result Parameters ---------- x_label : str, optional The label which is added to the X-axis. (default: "Method 1") y_label : str, optional The label which is added to the Y-axis. (default: "Method 2") title : str, optional Title of the regression plot. If None is provided, no title will be plotted. line_reference : bool, optional If True, a grey reference line at y=x will be plotted in the plot (default: True) line_CI : bool, optional If True, dashed lines will be plotted at the boundaries of the confidence intervals. (default: False) legend : bool, optional If True, will provide a legend containing the computed regression equation. (default: True) square : bool, optional If True, set the Axes aspect to "equal" so each cell will be square-shaped. (default: True) ax : matplotlib.axes.Axes, optional matplotlib axis object, if not passed, uses gca() point_kws : Optional[Dict], optional Additional keywords to plt color_regr : Optional[str], optional color for regression line and CI area alpha_regr : Optional[float], optional alpha for regression CI area Returns ------------------ matplotlib.axes.Axes axes object with the plot """ ax = ax or plt.gca() # Set scatter plot keywords to defaults and apply override pkws = self.DEFAULT_POINT_KWS.copy() pkws.update(point_kws or {}) # Get regression parameters slope = self.result["slope"] intercept = self.result["intercept"] # plot individual points ax.scatter(self.method1, self.method2, **pkws) # plot reference line if line_reference: ax.plot( [0, 1], [0, 1], label="Reference", color="grey", linestyle="--", transform=ax.transAxes, ) # Compute x and y values xvals = np.array(ax.get_xlim()) yvals = xvals[:, None] * slope + intercept # Plot regression line 0 ax.plot( xvals, yvals[:, 0], label= f"{y_label} = {intercept[0]:.2f} + {slope[0]:.2f} * {x_label}", color=color_regr, linestyle="-", ) # Plot confidence region if yvals.shape[1] > 2: ax.fill_between( xvals, yvals[:, 1], yvals[:, 2], color=color_regr or self.DEFAULT_REGRESSION_KWS["color"], alpha=alpha_regr or self.DEFAULT_REGRESSION_KWS["alpha"], ) if line_CI: ax.plot(xvals, yvals[:, 1], linestyle="--") ax.plot(xvals, yvals[:, 2], linestyle="--") # Set axes labels ax.set( xlabel=x_label or "", ylabel=y_label or "", title=title or "", ) if legend: ax.legend(loc="upper left", frameon=False) if square: ax.set_aspect("equal") return ax
def floor_plan( ax: mpl.axes.Axes, lattice: Lattice, *, start_angle: float = 0, labels: bool = True, ): ax.set_aspect("equal") codes = Path.MOVETO, Path.LINETO current_angle = start_angle start = np.zeros(2) end = np.zeros(2) x_min = y_min = 0 x_max = y_max = 0 sign = 1 for element, group in groupby(lattice.sequence): start = end.copy() length = element.length * sum(1 for _ in group) if isinstance(element, Drift): color = Color.BLACK line_width = 1 else: color = ELEMENT_COLOR[type(element)] line_width = 6 # TODO: refactor current angle angle = 0 if isinstance(element, Dipole): angle = element.k0 * length radius = length / angle vec = radius * np.array([np.sin(angle), 1 - np.cos(angle)]) sin = np.sin(current_angle) cos = np.cos(current_angle) rot = np.array([[cos, -sin], [sin, cos]]) end += rot @ vec angle_center = current_angle + 0.5 * np.pi center = start + radius * np.array( [np.cos(angle_center), np.sin(angle_center)]) diameter = 2 * radius arc_angle = -90 theta1 = current_angle * 180 / np.pi theta2 = (current_angle + angle) * 180 / np.pi if angle < 0: theta1, theta2 = theta2, theta1 line = patches.Arc( center, width=diameter, height=diameter, angle=arc_angle, theta1=theta1, theta2=theta2, color=color, linewidth=line_width, ) current_angle += angle else: end += length * np.array( [np.cos(current_angle), np.sin(current_angle)]) line = patches.PathPatch(Path((start, end), codes), color=color, linewidth=line_width) x_min = min(x_min, end[0]) y_min = min(y_min, end[1]) x_max = max(x_max, end[0]) y_max = max(y_max, end[1]) ax.add_patch(line) # TODO: currently splitted elements get drawn twice if labels and isinstance(element, (Dipole, Quadrupole)): angle_center = (current_angle - 0.5 * angle) + 0.5 * np.pi sign = -sign center = 0.5 * (start + end) + 0.5 * sign * np.array( [np.cos(angle_center), np.sin(angle_center)]) ax.annotate( element.name, xy=center, fontsize=6, ha="center", va="center", # rotation=(current_angle * 180 / np.pi -90) % 180, annotation_clip=False, zorder=11, ) margin = 0.01 * max((x_max - x_min), (y_max - y_min)) ax.set_xlim(x_min - margin, x_max + margin) ax.set_ylim(y_min - margin, y_max + margin) return ax