def plot_roc(roc: ROC, title: str = "", label: str = "", show=False, save=False, fig: plt.Figure = None): if fig is None: fig = plt.figure() ax = fig.add_axes([0.1, 0.1, 0.85, 0.8]) else: ax = fig.get_axes() assert len(ax) == 1 ax = ax[0] lw = 2 fpr, tpr, _ = roc ax.plot(fpr, tpr, lw=lw, label=label) ax.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--') ax.set(xlabel='FPR', ylabel='TPR', ylim=[0.0, 1.05], xlim=[0.0, 1.0]) ax.set_title(title, fontsize=15) ax.legend(loc="lower right") # fig.tight_layout() if show: fig.show() if save: fig.savefig(f'figs/{title}_{label}.png') return fig
def create_thumbnail(infile, thumbfile, width=180, height=180, xoffset=0, yoffset=0, zoom=1, cx=0.5, cy=0.6, dpi=100): from matplotlib import image from matplotlib.pyplot import Figure baseout, extout = os.path.splitext(thumbfile) im = image.imread(infile) thumb = padded_thumbnail(im, (height, width), (yoffset, xoffset), zoom) extension = extout.lower() if extension == '.png': from matplotlib.backends.backend_agg \ import FigureCanvasAgg as FigureCanvas elif extension == '.pdf': from matplotlib.backends.backend_pdf \ import FigureCanvasPDF as FigureCanvas elif extension == '.svg': from matplotlib.backends.backend_svg \ import FigureCanvasSVG as FigureCanvas else: raise ValueError("Can only handle extensions 'png', 'svg' or 'pdf'") fig = Figure(figsize=(float(width) / dpi, float(height) / dpi), dpi=dpi) canvas = FigureCanvas(fig) ax = fig.add_axes([0, 0, 1, 1], aspect='auto', frameon=False, xticks=[], yticks=[]) ax.imshow(thumb, aspect='auto', resample=True, interpolation='bilinear') fig.savefig(thumbfile, dpi=dpi) return fig
def add_relpath_to_top_corner(figure: plt.Figure): big_axis = figure.add_axes([0, 0, 1, 1], facecolor=(1, 1, 1, 0)) big_axis.text(0.99, 0.99, os.path.relpath(os.path.abspath(os.curdir), os.path.expanduser("~/bioinf/handling")), color="#CCCCCC", horizontalalignment='right', verticalalignment='top')
def add_inset_spectrum(figure: plt.Figure) -> plt.axis: rect_transform = [.7, .7, .25, .25] # (0,0 is bottom left; 1,1 is top right) _axis = figure.add_axes(rect_transform) _axis.get_xaxis().set_visible(False) # Hide tick labels _axis.get_yaxis().set_visible(False) # Hide tick labels _axis.set_yscale('log') # Set log scale return _axis
def add_track_spectrum(figure: plt.Figure) -> plt.axis: rect_transform = [0.125, 0.05, .775, .15] # (0,0 is bottom left; 1,1 is top right) _axis = figure.add_axes(rect_transform) _axis.get_xaxis().set_visible(False) # Hide tick labels _axis.get_yaxis().set_visible(False) # Hide tick labels _axis.set_yscale('log') # Set log scale _axis.set_facecolor('k') # Face color return _axis
def plot_test_sample(fig: plt.Figure, image: torch.Tensor, predictions: torch.Tensor, class_names: List[str], true_class: str, k: int = 10): """Plot test sample image with predictions on given Figure. Args: fig (plt.Figure): Figure to draw on. image (torch.Tensor): Image to draw. predictions (torch.Tensor): Preditions of network. class_names (List[str]): Class names true_class (str): True class of given image k (int, optional): How many best predictions to plot as bar plot. Defaults to 10. """ im_ax = fig.add_axes([0.0, 0.0, 2 / 3, 1.0]) pred_ax = fig.add_axes([2 / 3, 1 / 8, 1 / 3, 7 / 8]) plot_im(im_ax, image, true_class) plot_prediction_bar(pred_ax, predictions, class_names, k)
def isochrones_subfig( fig_: Figure, x_: np.ndarray, y_: np.ndarray, color_: str = gray_ ) -> Tuple[Axes, Tuple[float, float]]: r"""Generate an isochrones subfig for embedding.""" # Top left isochrones 0 size_zoom_0: Tuple[float, float] = (0.65, 0.55) posn_0: Tuple[float, float] = (0.0, 0.75) axes_0 = fig_.add_axes([*posn_0, *size_zoom_0]) plt.axis("off") n_isochrones = 6 for i_, sf_ in enumerate(np.linspace(0.5, 1.2, n_isochrones)): plt.plot( *(x_, sf_ * y_), "-", color=self.gray_color(i_, n_gray), lw=2.5, ) plt.xlim(0, 1) plt.ylim(0, 1) sf1_ = 1.3 sf2_ = 1.3 arrow_xy_: np.ndarray = np.array([0.2, 0.8]) arrow_dxy_: np.ndarray = np.array([-0.025, 0.15]) motion_xy_: Tuple[float, float] = (0.1, 0.8) motion_angle_ = 23 my_arrow_style = ArrowStyle.Simple( head_length=1 * sf1_, head_width=1 * sf1_, tail_width=0.1 * sf1_ ) axes_0.annotate( "", xy=arrow_xy_, xytext=arrow_xy_ + arrow_dxy_ * sf2_, transform=axes_0.transAxes, arrowprops=dict(arrowstyle=my_arrow_style, color=color_, lw=3), ) plt.text( *motion_xy_, "motion", color=color_, fontsize=16, rotation=motion_angle_, transform=axes_0.transAxes, horizontalalignment="center", verticalalignment="center", ) return (axes_0, posn_0)
def add_axes(fig: Figure, rct: Tuple[float, float, float, float], num: int) -> List[Axes]: """ add axes to figure in a rectangular with several panels vertically. :param fig: figure to add axes. :param rct: lower left point x, lower left point y, width, height. :param num: number of panels. :return: a list of axes. """ axs = [] x0, y0, w, h = rct width = w height = h / num for n in range(num): xax = x0 yax = y0 + h - (n + 1) * height ax = fig.add_axes([xax, yax, width, height]) axs.append(ax) return axs
def split_horizontal(fig: Figure, rct: Tuple[float, float, float, float], frac: float) -> Tuple[Axes, Axes]: """ create a axes in figure with two separate panels in horizontal. :param fig: figure to create axes. :param rct: lower left point x, lower left point y, width, height. :param frac: the fraction of left panel in width. :return: two axes. """ x, y, w, h = rct x0, y0 = x, y w0, h0 = w * frac, h x1, y1 = x + w0, y w1, h1 = w - w0, h rct0 = (x0, y0, w0, h0) rct1 = (x1, y1, w1, h1) ax0 = fig.add_axes(rct0) ax1 = fig.add_axes(rct1) return ax0, ax1
def zoom_boxes( fig_: Figure, ta_color_: str = gray2_, tb_color_: str = gray1_ ) -> Tuple[Axes, Axes, Axes, Axes, str]: # mpl.axes._axes. r"""Generate 'zoom' boxes.""" size_zoom_AB: Tuple[float, float] = (0.3, 0.7) size_zoom_C: Tuple[float, float] = (0.3, 0.7) n_pts: int = 300 def zoomed_isochrones( axes_: Axes, name_text: str, i_pt1_: Union[int, List[int]], i_pt2_: int, # Union[int, List[int]], do_many: bool = False, do_legend: bool = False, do_pts_only: bool = False, ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: """Generate isochrones for zoom box.""" x_array = np.linspace(-1, 3, n_pts) y_array1 = x_array * 0.5 y_array2 = y_array1 + 0.7 # Ta if not do_pts_only: plt.plot( x_array, y_array2, "-", color=ta_color_, lw=2.5, label=r"$T_a$", ) xy_pt2 = np.array([x_array[i_pt2_], y_array2[i_pt2_]]) marker_style2 = dict( marker="o", fillstyle="none", markersize=8, markeredgecolor=ta_color_, markerfacecolor=ta_color_, markeredgewidth=2, ) plt.plot(*xy_pt2, **marker_style2) if not do_pts_only: plt.text( *(xy_pt2 + np.array([-0.03, 0.08])), r"$\mathbf{a}$", color=ta_color_, fontsize=18, rotation=0, transform=axes_.transAxes, horizontalalignment="center", verticalalignment="center", ) # Tb if not do_pts_only: plt.plot( x_array, y_array1, "-", color=tb_color_, lw=2.5, label=r"$T_b = T_a+\Delta{T}$", ) # if isinstance(i_pt1_, List) else [i_pt1_] i_pts1: List = [i_pt1_] xy_pts1_tmp = np.array( [ np.array([x_array[i_pt1__], y_array1[i_pt1__]]) for i_pt1__ in i_pts1 ] ) xy_pts1 = ( xy_pts1_tmp.T.reshape((xy_pts1_tmp.shape[2], 2)) if do_many else xy_pts1_tmp ) marker_style1 = marker_style2.copy() marker_style1.update( {"markeredgecolor": tb_color_, "markerfacecolor": "w"} ) for xy_pt1_ in xy_pts1: plt.plot(*xy_pt1_, **marker_style1) if not do_pts_only: b_label_i = 4 if do_many else 0 b_label_xy = xy_pts1[b_label_i] + np.array([0.03, -0.08]) b_label_text = ( r"$\{\mathbf{b}\}$" if do_many else r"$\mathbf{b}$" ) plt.text( *b_label_xy, b_label_text, color=tb_color_, fontsize=18, rotation=0, transform=axes_.transAxes, horizontalalignment="center", verticalalignment="center", ) if do_legend: plt.legend(loc=[0.05, -0.35], fontsize=16, framealpha=0) name_xy = [0.97, 0.03] plt.text( *name_xy, name_text, color=brown_, fontsize=14, rotation=0, transform=axes_.transAxes, horizontalalignment="right", verticalalignment="bottom", ) dx = x_array[1] - x_array[0] dy = y_array1[1] - y_array1[0] return ( xy_pts1 if do_many else xy_pts1[0], xy_pt2, np.array([dx, dy]), ) def v_arrow( axes_: Axes, xy_pt1: np.ndarray, xy_pt2: np.ndarray, dxy: Tuple[float, float], a_f: float = 0.54, v_f: float = 0.5, v_label: str = r"$\mathbf{v}$", color_: str = red_, do_dashing: bool = False, do_label: bool = False, ) -> None: v_lw = 1.5 axes_.arrow( *((xy_pt1 * a_f + xy_pt2 * (1 - a_f))), *((xy_pt1 - xy_pt2) * 0.01), lw=1, facecolor=color_, edgecolor=color_, head_width=0.05, overhang=0.3, transform=axes_.transAxes, length_includes_head=True, ) axes_.plot( [xy_pt1[0], xy_pt2[0]], [xy_pt1[1], xy_pt2[1]], ls="--" if do_dashing else "-", lw=v_lw, color=color_, ) f = v_f v_xy = ( xy_pt1[0] * f + xy_pt2[0] * (1 - f) + dxy[0], xy_pt1[1] * f + xy_pt2[1] * (1 - f) + dxy[1], ) if do_label: axes_.text( *v_xy, v_label, color=color_, fontsize=18, rotation=0, transform=axes_.transAxes, horizontalalignment="right", verticalalignment="bottom", ) def p_bones( axes_: Axes, xy_pt1: np.ndarray, xy_pt2: np.ndarray, dxy: np.ndarray, p_f: float = 0.9, color_: str = blue_, n_bones: int = 5, do_primary: bool = True, ) -> None: alpha_ = 0.7 p_dashing = [1, 0] # [4, 4] p_lw = 3 axes_.plot( [xy_pt1[0], xy_pt2[0]], [xy_pt1[1], xy_pt2[1]], dashes=p_dashing, lw=p_lw, color=color_, alpha=1 if do_primary else alpha_, ) bones = np.linspace(1, 0, n_bones, endpoint=False) for i_, f in enumerate(bones): x = xy_pt1[0] * f + xy_pt2[0] * (1 - f) y = xy_pt1[1] * f + xy_pt2[1] * (1 - f) sf = 4 if do_primary else 3 dx = dxy[0] * sf dy = dxy[1] * sf x_pair = [x - dx, x + dx] y_pair = [y - dy, y + dy] axes_.plot( x_pair, y_pair, lw=5 if i_ == 0 else 2.5, color=color_, alpha=1 if do_primary else alpha_, ) f = p_f p_xy = ( xy_pt1[0] * f + xy_pt2[0] * (1 - f) - 0.1, xy_pt1[1] * f + xy_pt2[1] * (1 - f) - 0.1, ) if do_primary: axes_.text( *p_xy, r"$\mathbf{\widetilde{p}}$", color=color_, fontsize=18, rotation=0, transform=axes_.transAxes, horizontalalignment="right", verticalalignment="bottom", ) def psi_label( axes_: Axes, xy_pt1_B: np.ndarray, xy_pt2_B: np.ndarray, xy_pt1_C: np.ndarray, xy_pt2_C: np.ndarray, color_: str = red_, ) -> None: label_xy = [0.5, 0.53] axes_.text( *label_xy, r"$\psi$", color=color_, fontsize=20, rotation=0, transform=axes_.transAxes, horizontalalignment="center", verticalalignment="center", ) angle_B = np.rad2deg( np.arctan( (xy_pt2_B[1] - xy_pt1_B[1]) / (xy_pt2_B[0] - xy_pt1_B[0]) ) ) angle_C = np.rad2deg( np.arctan( (xy_pt2_C[1] - xy_pt1_C[1]) / (xy_pt2_C[0] - xy_pt1_C[0]) ) ) radius = 0.95 axes_.add_patch( Arc( xy_pt2_B, radius, radius, color=color_, linewidth=2, fill=False, zorder=2, # transform=axes_.transAxes, angle=angle_B, theta1=0, theta2=angle_C - angle_B, ) ) def beta_label( axes_: Axes, xy_pt1_B: np.ndarray, xy_pt2_B: np.ndarray, color_: str = blue_, ) -> None: label_xy = [0.28, 0.47] axes_.text( *label_xy, r"$\beta$", color=color_, fontsize=20, rotation=0, transform=axes_.transAxes, horizontalalignment="center", verticalalignment="center", ) angle_ref = -90 angle_B = np.rad2deg( np.arctan( (xy_pt2_B[1] - xy_pt1_B[1]) / (xy_pt2_B[0] - xy_pt1_B[0]) ) ) radius = 0.88 axes_.add_patch( Arc( xy_pt2_B, radius, radius, color=color_, linestyle="--", linewidth=2, fill=False, zorder=2, # transform=axes_.transAxes, angle=angle_ref, theta1=0, theta2=angle_B - angle_ref, ) ) axes_.plot( [xy_pt2_B[0], xy_pt2_B[0]], [xy_pt2_B[1], xy_pt2_B[1] - 0.5], ":", color=color_, ) def alpha_label( axes_: Axes, xy_pt1_B: np.ndarray, xy_pt2_B: np.ndarray, color_: str = red_, ) -> None: label_xy = [0.55, 0.75] axes_.text( *label_xy, r"$-\alpha$", color=color_, fontsize=20, rotation=0, transform=axes_.transAxes, horizontalalignment="center", verticalalignment="center", ) # angle_ref = 0 angle_B = np.rad2deg( np.arctan( (xy_pt2_B[1] - xy_pt1_B[1]) / (xy_pt2_B[0] - xy_pt1_B[0]) ) ) radius = 0.88 axes_.add_patch( Arc( xy_pt2_B, radius, radius, color=color_, linestyle="--", linewidth=2, fill=False, zorder=2, # transform=axes_.transAxes, angle=angle_B, theta1=0, theta2=-angle_B, ) ) axes_.plot( [xy_pt2_B[0], xy_pt2_B[0] + 0.5], [xy_pt2_B[1], xy_pt2_B[1]], ":", color=color_, ) # From zoom box D posn_D = np.array(posn_0) + np.array([0.19, 0.25]) size_zoom_D = [0.042, 0.1] axes_D = fig_.add_axes([*posn_D, *size_zoom_D]) remove_ticks_etc(axes_D) axes_D.patch.set_alpha(0.5) # Zoom any point pairing A posn_A = [0, 0.15] axes_A = fig_.add_axes([*posn_A, *size_zoom_AB]) remove_ticks_etc(axes_A) i_pt2_A = 92 i_pts1_A = [i_pt2_A + i_ for i_ in np.arange(-43, 100, 15)] # logging.info(type(i_pts1_A)) (xy_pts1_A, xy_pt2_A, _) = zoomed_isochrones( axes_A, "free", i_pts1_A, i_pt2_A, do_many=True ) for i_, xy_pt1_A in enumerate(xy_pts1_A): v_arrow( axes_A, xy_pt1_A, xy_pt2_A, dxy=(0.12, 0.05), do_dashing=True, v_f=0.35, v_label=r"$\{\mathbf{v}\}$", do_label=bool(i_ == len(xy_pts1_A) - 1), ) _ = zoomed_isochrones(axes_A, "", i_pts1_A, i_pt2_A, do_many=True) # Zoom intrinsic pairing B posn_B = [0.33, 0.28] axes_B = fig_.add_axes([*posn_B, *size_zoom_AB]) remove_ticks_etc(axes_B) i_pt2_B = i_pt2_A i_pt1_B = i_pt2_A + 19 (xy_pt1_B, xy_pt2_B, dxy_B) = zoomed_isochrones( axes_B, "isotropic", i_pt1_B, i_pt2_B ) p_bones(axes_B, xy_pt1_B, xy_pt2_B, dxy_B) v_arrow( axes_B, xy_pt1_B, xy_pt2_B, v_f=0.5, dxy=(0.13, 0.02), do_label=True, ) _ = zoomed_isochrones( axes_B, "", i_pt1_B, i_pt2_B, do_pts_only=True ) # Zoom erosion-fn pairing C posn_C = [0.66, 0.6] axes_C = fig_.add_axes([*posn_C, *size_zoom_C]) remove_ticks_etc(axes_C) i_pt1_C = i_pt1_B + 30 i_pt2_C = i_pt2_B (xy_pt1_C, xy_pt2_C, dxy_C) = zoomed_isochrones( axes_C, "anisotropic", i_pt1_C, i_pt2_C, do_legend=True ) p_bones(axes_C, xy_pt1_C, xy_pt2_C, dxy_C, do_primary=False) p_bones(axes_C, xy_pt1_B, xy_pt2_B, dxy_B) v_arrow( axes_C, xy_pt1_C, xy_pt2_C, a_f=0.8, v_f=0.72, dxy=(0.1, 0.05), do_label=True, ) _ = zoomed_isochrones( axes_C, "", i_pt1_C, i_pt2_C, do_legend=False, do_pts_only=True ) psi_label( axes_C, xy_pt1_B, xy_pt2_B, xy_pt1_C, xy_pt2_C, color_=purple_ ) beta_label(axes_C, xy_pt1_B, xy_pt2_B) alpha_label(axes_C, xy_pt1_C, xy_pt2_C) # Brown zoom boxes and tie lines set_colors(Spine, [axes_A, axes_B, axes_C, axes_D], brown_) return axes_A, axes_B, axes_C, axes_D, brown_