def plot_plate_trajectories(featurefilepath, saveDir=None, downsample=10, filter_trajectories=False, mark_endpoints=False, del_if_exists=False): """ Tile plots and merge into a single plot for the entire 96-well plate, correcting for camera orientation. """ file_dict = get_video_set(featurefilepath) # define multi-panel figure columns = 3 rows = 2 x = 25.5 y = 16 plt.ioff() if saveDir else plt.ion() plt.close('all') fig, axs = plt.subplots(rows,columns,figsize=[x,y]) x_offset = 1.5 / x # for bottom left image width = 0.3137 # for all but top left image width_tl = 0.3725 # for top left image height = 0.5 # for all images errlog = [] for channel, (maskedfilepath, featurefilepath) in file_dict.items(): if saveDir: saveName = maskedfilepath.parent.stem + ('_filtered.png' if filter_trajectories else '.png') savePath = Path(saveDir) / saveName if savePath.exists(): if del_if_exists: os.remove(savePath) else: print("Skipping file '%s' (already exists)" % savePath.name) continue _loc, rotate = CH2PLATE_dict[channel] _ri, _ci = _loc # create bbox for image layout in figure if (_ri == 0) and (_ci == 0): # first image (with well names), bbox slightly shifted bbox = [0, height, width_tl, height] else: # other images bbox = [x_offset + width * _ci, height * (rows - (_ri + 1)), width, height] # get location of subplot for camera ax = axs[_loc] try: # plot first frame of video + annotate wells FOVsplitter = FOVMultiWellsSplitter(maskedfilepath) FOVsplitter.plot_wells(is_rotate180=rotate, ax=ax, line_thickness=10) # plot worm trajectories plot_trajectory(featurefilepath, downsample=downsample, filter_trajectories=filter_trajectories, mark_endpoints=mark_endpoints, rotate=rotate, img_shape=FOVsplitter.img_shape, legend=False, ax=ax) except Exception as e: print("WARNING: Could not plot video file: '%s'\n%s" % (maskedfilepath, e)) errlog.append(maskedfilepath) # set image position in figure ax.set_position(bbox) if saveDir: if savePath.exists(): print("Skipping file '%s' (already exists)" % savePath.name) else: Path(saveDir).mkdir(exist_ok=True, parents=True) fig.savefig(savePath, bbox_inches='tight', dpi=300, pad_inches=0, transparent=True) print(errlog) # TODO: Save errlog to file? return
def plot_plate_trajectories(featurefilepath, saveDir=None, downsample=10): """ Tile plots and merge into a single plot for the entire 96-well plate, correcting for camera orientation. """ from tierpsy.analysis.split_fov.FOVMultiWellsSplitter import FOVMultiWellsSplitter file_dict = get_video_set(featurefilepath) # define multi-panel figure columns = 3 rows = 2 h_in = 6 x_off_abs = (3600 - 3036) / 3036 * h_in x = columns * h_in + x_off_abs y = rows * h_in fig, axs = plt.subplots(rows, columns, figsize=[x, y]) x_offset = x_off_abs / x # for bottom left image width = (1 - x_offset) / columns # for all but top left image width_tl = width + x_offset # for top left image height = 1 / rows # for all images for channel, ch_featfilepath in file_dict.items(): _loc, rotate = CH2PLATE_dict[channel] _ri, _ci = _loc # create bbox for image layout in figure if (_ri == 0) and (_ci == 0): # first image (with well names), bbox slightly shifted bbox = [0, height, width_tl, height] else: # other images bbox = [ x_offset + width * _ci, height * (rows - (_ri + 1)), width, height ] # get location of subplot for camera ax = axs[_loc] # plot first frame of video + annotate wells fovsplitter = FOVMultiWellsSplitter(ch_featfilepath) # let's check if the fovsplitter managed to get a frame automatically if fovsplitter.img is None: fovsplitter.img = get_frame_from_raw(feat2raw(ch_featfilepath)) fovsplitter.plot_wells(is_rotate180=rotate, ax=ax, line_thickness=10) # plot worm trajectories plot_trajectory(ch_featfilepath, ax=ax, downsample=downsample, legend=False, rotate=rotate, img_shape=fovsplitter.img_shape) # set image position in figure ax.set_position(bbox) plt.show() if saveDir: saveName = Path(featurefilepath).parent.stem + '.png' savePath = Path(saveDir) / saveName fig.savefig(savePath, bbox_inches='tight', dpi=300, pad_inches=0, transparent=True) return (fig)