def plot_area_timeseries(self): """ Plot all the area changes over time """ # Plot the areas over time if self.tile_outdir is None: outfile = None else: outfile = f'Areas-{self.tile}{self.suffix}' outfile = self.tile_outdir / outfile with set_plot_style(self.plot_style) as style: fig, ax = plt.subplots(1, 1, figsize=self.figsize) ax.plot(np.arange(len(self.areas)), self.areas) ax.set_title('Colony area over time') ax.set_xlabel('Frame #') ax.set_ylabel('Colony area') style.show(outfile, tight_layout=True) # Plot the delta area over time if self.tile_outdir is None: outfile = None else: outfile = f'DeltaAreas-{self.tile}{self.suffix}' outfile = self.tile_outdir / outfile with set_plot_style(self.plot_style) as style: fig, ax = plt.subplots(1, 1, figsize=self.figsize) ax.plot(np.arange(len(self.delta_areas)), self.delta_areas) ax.set_title('Change in colony area (dA/$A_0$)') ax.set_xlabel('Frame #') ax.set_ylabel('Delta colony area (dA/$A_0$)') style.show(outfile, tight_layout=True)
def plot_persistence_timeseries(self): """ Plot the persistent tracks on one plot """ if self.tile_outdir is None: outfile = None else: outfile = self.tile_outdir / f'Tracks-{self.tile}{self.suffix}' with set_plot_style(self.plot_style) as style: fig, ax = plt.subplots(1, 1, figsize=self.figsize) ax.plot(self.perimeters[-1][:, 0], self.perimeters[-1][:, 1], '-r', linewidth=2) for track in self.grid.track_peristences.values(): if track is None: continue add_gradient_line(ax, track.xx / self.grid.space_scale, track.yy / self.grid.space_scale, track.mask, vmin=-0.1, vmax=1.1, cmap='Dark2') ax.autoscale_view() ax.set_xticks([]) ax.set_yticks([]) ax.set_aspect('equal') ax.set_axis_off() style.show(outfile, tight_layout=True)
def plot_field(self, fieldname: str): """ Plot all the properties for the field :param str fieldname: The name of the field to plot """ mean_field = getattr(self, f'mean_{fieldname}') mean_warp_field = getattr(self, f'mean_warp_{fieldname}') cmap = getattr(self, f'{fieldname}_cmap') vmin = getattr(self, f'mean_{fieldname}_min') vmax = getattr(self, f'mean_{fieldname}_max') # Plot the unwarped field if mean_field is None: print(f'No mean field data for {fieldname}') else: if self.tile_outdir is None: outfile = None else: outfile = f'{fieldname.capitalize()}-{self.tile}{self.suffix}' outfile = self.tile_outdir / outfile with set_plot_style(self.plot_style) as style: fig, ax = plt.subplots(1, 1, figsize=self.figsize) ax.imshow(mean_field, cmap=cmap, vmin=vmin, vmax=vmax) ax.set_xticks([]) ax.set_yticks([]) style.show(outfile, tight_layout=True) # Plot the warped field if mean_warp_field is None: print(f'No mean warp field data for {fieldname}') else: if self.tile_outdir is None: outfile = None else: outfile = f'Warp{fieldname.capitalize()}-{self.tile}{self.suffix}' outfile = self.tile_outdir / outfile with set_plot_style(self.plot_style) as style: fig, ax = plt.subplots(1, 1, figsize=self.figsize) ax.imshow(mean_warp_field, cmap=cmap, vmin=vmin, vmax=vmax) ax.set_xticks([]) ax.set_yticks([]) style.show(outfile, tight_layout=True)
def plot_perimeter_timeseries(self): """ Plot the perimeters on one plot """ # FIXME: Should we smooth them first? if self.tile_outdir is None: outfile = None else: outfile = f'Perimeters-{self.tile}{self.suffix}' outfile = self.tile_outdir / outfile with set_plot_style(self.plot_style) as style: fig, ax = plt.subplots(1, 1, figsize=self.figsize) for perimeter in self.perimeters: ax.plot(perimeter[:, 0], perimeter[:, 1]) ax.set_xticks([]) ax.set_yticks([]) style.show(outfile, tight_layout=True)
def plot_parameter_violins(self, parameter_name: str, num_bins: int, bin_type: str = 'area', graphic: str = 'violin'): """ Plot violin distributions for different parameters :param str parameter_name: Name of the parameter to plot :param int num_bins: Number of radial bins to divide the data into :param str bin_type: How to equally divide the bins (one of 'radius' or 'area') :param str graphic: Which graphic to plot the parameters on ('violin', 'bins', 'boxes') """ if parameter_name in ('divergence', 'curl'): extremes = 'both' else: extremes = 'upper' radius_attr = 'track_radius' parameter_attr = f'track_mean_{parameter_name}' radius_data = getattr(self, radius_attr, None) parameter_data = getattr(self, parameter_attr, None) if radius_data is None or parameter_data is None: print(f'No radial data for {parameter_attr} vs {radius_attr}') return None ymin, ymax = CATEGORY_LIMITS.get(parameter_name, (None, None)) ylabel = CATEGORY_LABELS.get(parameter_name, None) print(f'Plotting {parameter_attr} vs {radius_attr}') # Bin the gridded density data = bin_by_radius(radius_data, parameter_data, num_bins=num_bins, bin_type=bin_type, label=parameter_name.capitalize()) # Calculate the significance significance = calc_pairwise_significance( data, category='Radius', score=parameter_name.capitalize()) ycolumn = parameter_name.capitalize() if self.tile_outdir is None: outfile = None else: outfile = f'{ycolumn}VsRadius-{graphic}-{self.tile}-{num_bins:d}bins{self.suffix}' outfile = self.tile_outdir / outfile with set_plot_style(self.plot_style) as style: fig, ax = plt.subplots(1, 1, figsize=self.violin_figsize) add_violins_with_outliers(ax, data, xcolumn='Radius', ycolumn=ycolumn, extremes=extremes, significance=significance, savefile=outfile, graphic=graphic, ymin=ymin, ymax=ymax, ylabel=ylabel) style.show(outfile, tight_layout=True) return significance
def plot_single_timepoint_mesh_field(self, fieldname: str, timepoint: int): """ Plot the field and mesh from a single timepoint :param str fieldname: The field to load :param int timepoint: The timepoint to load """ coords = self.load_coord_mesh('image', timepoint) warp_coords = self.load_coord_mesh('warp', timepoint) tris = self.load_coord_mesh('tris', timepoint) field = self.load_field_mesh(fieldname, timepoint) cmap = getattr(self, f'{fieldname}_cmap') vmin = getattr(self, f'{fieldname}_min') vmax = getattr(self, f'{fieldname}_max') if fieldname in ('distance', 'displacement'): max_timepoint = max(self.all_timepoints) vmin = vmin * (timepoint / max_timepoint) vmax = vmax * (timepoint / max_timepoint) rows, cols = self.timepoint_image_shapes.get( timepoint, (np.max(coords[:, 0]), np.max(coords[:, 1]))) name = fieldname.capitalize() # Plot the triangulation over the original image if self.tile_outdir is None: outfile = None else: outfile = f'{name}-{self.tile}t{timepoint:03d}{self.suffix}' outfile = self.tile_outdir / name / outfile outfile.parent.mkdir(exist_ok=True, parents=True) with set_plot_style(self.plot_style) as style: fig, ax = plt.subplots(1, 1, figsize=self.figsize) add_poly_meshplot(ax, coords, tris, field, vmin=vmin, vmax=vmax, cmap=cmap) ax.set_xlim([0, cols]) ax.set_ylim([rows, 0]) ax.set_xticks([]) ax.set_yticks([]) ax.set_aspect('equal') ax.set_axis_off() style.show(outfile, tight_layout=True) # Plot the warped mesh if self.tile_outdir is None: outfile = None else: outfile = f'Warp{name}-{self.tile}t{timepoint:03d}{self.suffix}' outfile = self.tile_outdir / f'Warp{name}' / outfile outfile.parent.mkdir(exist_ok=True, parents=True) with set_plot_style(self.plot_style) as style: fig, ax = plt.subplots(1, 1, figsize=self.figsize) add_poly_meshplot(ax, warp_coords, tris, field, vmin=vmin, vmax=vmax, cmap=cmap) ax.set_xlim([-1.1, 1.1]) ax.set_ylim([-1.1, 1.1]) ax.set_xticks([]) ax.set_yticks([]) ax.set_aspect('equal') ax.set_axis_off() style.show(outfile, tight_layout=True)
def plot_single_timepoint_mesh(self, timepoint: int): """ Plot the mesh at a single timepoint :param int timepoint: Timepoint to plot the mesh at """ # Load the image to plot over imagefile = find_timepoint(self.imagedir, tile=self.tile, timepoint=timepoint) image = load_image(imagefile) # Load the mesh to plot points = self.load_coord_mesh('image', timepoint) warp_points = self.load_coord_mesh('warp', timepoint) mesh = self.load_coord_mesh('mesh', timepoint) if len(self.perimeters) > timepoint: perimeter = self.perimeters[timepoint] else: perimeter = None rows, cols = image.shape[:2] self.timepoint_image_shapes[timepoint] = (rows, cols) # Plot the triangulation over the original image if self.tile_outdir is None: outfile = None else: outfile = f'Mesh-{self.tile}t{timepoint:03d}{self.suffix}' outfile = self.tile_outdir / 'Mesh' / outfile outfile.parent.mkdir(parents=True, exist_ok=True) with set_plot_style(self.plot_style) as style: fig, ax = plt.subplots(1, 1, figsize=self.figsize) ax.imshow(image, cmap='bone') add_meshplot(ax, points, mesh) ax.set_xlim([0, cols]) ax.set_ylim([rows, 0]) ax.set_xticks([]) ax.set_yticks([]) ax.set_aspect('equal') ax.set_axis_off() style.show(outfile, tight_layout=True) # Plot the current perimeter if perimeter is not None: if self.tile_outdir is None: outfile = None else: outfile = f'Perimeter-{self.tile}t{timepoint:03d}{self.suffix}' outfile = self.tile_outdir / 'Perimeter' / outfile outfile.parent.mkdir(parents=True, exist_ok=True) with set_plot_style(self.plot_style) as style: fig, ax = plt.subplots(1, 1, figsize=self.figsize) ax.plot(perimeter[:, 0], perimeter[:, 1], '-r') ax.imshow(image, cmap='bone') ax.set_xlim([0, cols]) ax.set_ylim([rows, 0]) ax.set_xticks([]) ax.set_yticks([]) ax.set_aspect('equal') ax.set_axis_off() style.show(outfile, tight_layout=True) # Plot the warped mesh if self.tile_outdir is None: outfile = None else: outfile = f'Warp-{self.tile}t{timepoint:03d}{self.suffix}' outfile = self.tile_outdir / 'Warp' / outfile outfile.parent.mkdir(parents=True, exist_ok=True) with set_plot_style(self.plot_style) as style: fig, ax = plt.subplots(1, 1, figsize=self.figsize) add_meshplot(ax, warp_points, mesh) ax.set_xlim([-1.1, 1.1]) ax.set_ylim([-1.1, 1.1]) ax.set_xticks([]) ax.set_yticks([]) ax.set_aspect('equal') ax.set_axis_off() style.show(outfile, tight_layout=True)