def main(): # Parse arguments parser = argparse.ArgumentParser() parser.add_argument('--blc', nargs=2, type=int, help='Bottom left corner of the data box') parser.add_argument('--trc', nargs=2, type=int, help='Top right corner of the data box') parser.add_argument('image', type=str, help='FITS file name') parser.add_argument('out', type=str, help='Output plot file name') args = parser.parse_args() # Open data img = fits.open(os.path.expanduser(args.image))[0] data = np.squeeze(img.data) # Select data npix, x0, x1, y0, y1 = select_data(data.shape, blc=args.blc, trc=args.trc) # Create figure fig, ax = get_figure(npix) # Plot if args.trc and args.blc: ax.imshow(data[y0:y1, x0:x1]) else: ax.imshow(data) # Save fig.savefig(args.out, dpi=600)
def figure_10c(**kwargs): fig = utils.get_figure(.425, aspect_ratio=1 / utils.golden_ratio) # ax_upper = fig.add_subplot(211) # ax_lower = fig.add_subplot(212) ax_upper = fig.add_axes([.2, .6, .75, .25]) ax_lower = fig.add_axes([.2, .1, .75, .25]) axes = (ax_upper, ax_lower) basis_upper = BSplineBasis([0, 0, 0, 1, 1, 1], polynomial_order=2) basis_lower = BSplineBasis([0, 0, 0, 1 / 3, 2 / 3, 1, 1, 1], polynomial_order=2) bases = (basis_upper, basis_lower) titles = ( r"$\Xi' = \left\lbrace 0, 0, 0, 1, 1, 1 \right\rbrace, \, p = 2$", r"$\Xi'' = \left\lbrace 0, 0, 0, \frac{1}{3}, \frac{2}{3}, 1, 1, 1 \right\rbrace, \, p = 2$" ) method = (r'$p$-refinement \\ (order elevation)', r'$h$-refinement \\ (knot insertion)') for ax, basis, title, method in zip(axes, bases, titles, method): basis.attach_basis_functions(ax) title_size = 10 ax.set_ylabel(r'$N_{i, \,p}\left(\xi\right)$', fontsize=title_size) ax.set_xlabel(r'$\xi$', fontsize=title_size) ax.set_title(title, fontsize=title_size) ax.set_xlim(0, 1.0) ax.set_ylim(0, 1.0) ax.grid(True, **GRID_KWARGS) ax.annotate( s=method, xy=(0.5, 1.275), xycoords='axes fraction', xytext=(10, 8), textcoords='offset points', fontsize=title_size, ) ax.annotate(s='', xy=(0.5, 1.275), xycoords='axes fraction', xytext=(0, 25), textcoords='offset points', arrowprops=dict( width=1, facecolor='black', headlength=10, )) # plt.tight_layout() utils.save_current_figure('fig_10c', tight=False, **kwargs) plt.close()
def plot_curve_3D(self, length=30, fps=30, **kwargs): """Only works in 3D...""" fig = utils.get_figure(scale=3) ax = fig.add_subplot(111, projection='3d') curve_x, curve_y, curve_z = self.curve() control_points_x = np.array( [control_point[0] for control_point in self.control_points]) control_points_y = np.array( [control_point[1] for control_point in self.control_points]) control_points_z = np.array( [control_point[2] for control_point in self.control_points]) x_min = min(np.min(curve_x), np.min(control_points_x)) x_max = max(np.max(curve_x), np.max(control_points_x)) x_range = np.abs(x_max - x_min) y_min = min(np.min(curve_y), np.min(control_points_y)) y_max = max(np.max(curve_y), np.max(control_points_y)) y_range = np.abs(y_max - y_min) z_min = min(np.min(curve_z), np.min(control_points_z)) z_max = max(np.max(curve_z), np.max(control_points_z)) z_range = np.abs(z_max - z_min) ax.set_xlim(x_min - 0.05 * x_range, x_max + 0.05 * x_range) ax.set_ylim(y_min - 0.05 * y_range, y_max + 0.05 * y_range) ax.set_zlim(z_min - 0.05 * z_range, z_max + 0.05 * z_range) ax.plot(control_points_x, control_points_y, control_points_z, **CONTROL_POLYGON_KWARGS) ax.plot(curve_x, curve_y, curve_z, **CURVE_KWARGS) ax.axis('off') ax.view_init( elev=45, azim=0 ) # note that this resets ax.dist to 10, so we can't use it below ax.dist = 7.5 # default is 10, so zoom in a little because there's no axis to take up the rest of the space ### ANIMATION ### frames = length * fps writer = anim.writers['ffmpeg']( fps=fps, bitrate=2000) # don't need a very high bitrate def animate(frame): print(frame, frames, frame / frames) ax.azim = 360 * frame / frames # one full rotation return [ ] # must return the list of artists we modified (i.e., nothing, since all we did is rotate the view) ani = anim.FuncAnimation(fig, animate, frames=frames, blit=True) ani.save(f"{os.path.join(kwargs['target_dir'], kwargs['name'])}.mp4", writer=writer) plt.close()
def plot_curve_2D(self, fig_scale='full', **kwargs): """Only works in 2D...""" fig = utils.get_figure(fig_scale) ax = fig.add_subplot(111) self.attach_curve_2D(ax) utils.save_current_figure(**kwargs) plt.close()
def figure_10a(**kwargs): fig = utils.get_figure('half') ax = fig.add_subplot(111) basis = BSplineBasis([0, 0, 1, 1], polynomial_order=1) basis.attach_basis_functions(ax) title_size = 10 ax.set_xlabel(r'$\xi$', fontsize=title_size) ax.set_ylabel(r'$N_{i, \,p}\left(\xi\right)$', fontsize=title_size) ax.set_title(r'$\Xi = \left\lbrace 0, 0, 1, 1 \right\rbrace, \, p = 1$', fontsize=title_size) ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.grid(True, **GRID_KWARGS) utils.save_current_figure('fig_10a', **kwargs) plt.close()
def plot_basis_functions(self, fig_scale='full', title=True, legend_on_right=True, **kwargs): fig = utils.get_figure(fig_scale) ax = fig.add_subplot(111) self.attach_basis_functions(ax) ax.set_xlim(self.xi_min, self.xi_max) ax.set_ylim(0, 1.01) ax.set_xlabel(r'$\xi$', fontsize=12) ax.set_ylabel(r'$N_{i,p}(\xi)$', fontsize=12) if title: ax.set_title( fr'Basis Functions for $\Xi = \left\lbrace {",".join(str(s) for s in self.knot_vector)} \right\rbrace$, $p = {self.polynomial_order}$' ) if legend_on_right: ax.legend(bbox_to_anchor=(1.02, 1), loc='upper left', borderaxespad=0., fontsize=12, handlelength=1, ncol=1 + (len(self.basis_function_indices) // 15)) else: ax.legend(loc='upper right', handlelength=1) ax.grid(True, **GRID_KWARGS) utils.save_current_figure(name=self.name + '__basis', **kwargs) plt.close()
def figure_9(**kwargs): fig = utils.get_figure('full', aspect_ratio=.8) ax_original_curve = fig.add_subplot(221) ax_original_basis = fig.add_subplot(223) ax_new_curve = fig.add_subplot(222) ax_new_basis = fig.add_subplot(224) original_basis = BSplineBasis([0, 0, 0, 1, 1, 1], polynomial_order=2) original_curve = BSplineCurve(original_basis, [(0, 0), (.5, 1), (1, 0)]) title_size = 10 ax_original_curve.set_title( r'Original Curve: $\Xi = \left\lbrace0, 0, 0, 1, 1, 1\right\rbrace, \; p = 2$', fontsize=title_size) ax_original_basis.set_title(r'Original Basis Functions', fontsize=title_size) ax_new_curve.set_title( r"$p$-Refined Curve: $\Xi' = \left\lbrace0, 0, 0, 0, 1, 1, 1, 1\right\rbrace, \; p = 3$", fontsize=title_size) ax_new_basis.set_title(r'$p$-Refined Basis Functions', fontsize=title_size) new_basis = BSplineBasis([0, 0, 0, 0, 1, 1, 1, 1], polynomial_order=3) new_curve = BSplineCurve(new_basis, [(0, 0), (1 / 3, 2 / 3), (2 / 3, 2 / 3), (1, 0)]) for ax, basis in ((ax_original_curve, original_curve), (ax_new_curve, new_curve)): basis.attach_curve_2D(ax) ax.set_xlim(-.05, 1.05) ax.set_ylim(-.05, 1.05) ax.grid(True, linewidth=.5) ax.axis('on') ax.set_xticks((0, 1 / 3, 2 / 3, 1)) ax.set_xticklabels(( r'$0$', r'$\frac{1}{3}$', r'$\frac{2}{3}$', r'$1$', )) ax.set_yticks((0, 2 / 3, 1)) ax.set_yticklabels(( r'$0$', r'$\frac{2}{3}$', r'$1$', )) for ax, basis in ((ax_original_basis, original_basis), (ax_new_basis, new_basis)): basis.attach_basis_functions(ax) ax.set_xlim(0, 1.0) ax.set_ylim(0, 1.0) ax.set_xlabel(r'$\xi$') ax.grid(True, **GRID_KWARGS) ax_original_basis.set_ylabel(r'$N_{i, \,p}\left(\xi\right)$') plt.tight_layout() utils.save_current_figure('fig_9', **kwargs) plt.close()
def plot_surface_3D(self, length=30, fps=30, **kwargs): """Only works in 3D...""" fig = utils.get_figure(scale=3) ax = fig.add_subplot(111, projection='3d') # surface_x = self.xi_1_mesh # surface_y = self.xi_2_mesh # surface_x, surface_y, surface_z = self.surface() xyz = self.surface() # surface_x, surface_y = np.meshgrid(surface_x, surface_y) # print(np.shape(surface_x)) # print(np.shape(surface_y)) # print(np.shape(surface_z)) control_points_x = np.array( [control_point[0] for control_point in self.control_net.values()]) control_points_y = np.array( [control_point[1] for control_point in self.control_net.values()]) control_points_z = np.array( [control_point[2] for control_point in self.control_net.values()]) # x_min = min(np.min(surface_x), np.min(control_points_x)) # x_max = max(np.max(surface_x), np.max(control_points_x)) # x_range = np.abs(x_max - x_min) # # y_min = min(np.min(surface_y), np.min(control_points_y)) # y_max = max(np.max(surface_y), np.max(control_points_y)) # y_range = np.abs(y_max - y_min) # # z_min = min(np.min(surface_z), np.min(control_points_z)) # z_max = max(np.max(surface_z), np.max(control_points_z)) # z_range = np.abs(z_max - z_min) # # ax.set_xlim(x_min - 0.05 * x_range, x_max + 0.05 * x_range) # ax.set_ylim(y_min - 0.05 * y_range, y_max + 0.05 * y_range) # ax.set_zlim(z_min - 0.05 * z_range, z_max + 0.05 * z_range) ax.scatter(control_points_x, control_points_y, control_points_z, depthshade=False, **CONTROL_POLYGON_KWARGS) # print(np.max(surface_x), np.max(surface_y), np.max(surface_z)) # print(np.min(surface_x), np.min(surface_y), np.min(surface_z)) # print(surface_x) # print(surface_y) # print(surface_z) xyz = np.reshape(xyz, (-1, 3)) print(xyz.shape) x, y, z = xyz[:, 0], xyz[:, 1], xyz[:, 2] ax.scatter(x, y, z) # ax.plot_trisurf( # x, y, z, # cmap = plt.get_cmap('viridis'), # linewidth = 0, # antialiased = True, # ) # ax.plot_surface(surface_x, surface_y, surface_z, rstride = 1, cstride = 1) # ax.plot_trisurf(surface_x, surface_y, surface_z) # ax.plot_trisurf(surface_x, surface_y, surface_z, **CURVE_KWARGS) ax.axis('off') ax.view_init( elev=45, azim=0 ) # note that this resets ax.dist to 10, so we can't use it below ax.dist = 7.5 # default is 10, so zoom in a little because there's no axis to take up the rest of the space plt.show() utils.save_current_figure(**kwargs) ### ANIMATION ### frames = length * fps writer = anim.writers['ffmpeg']( fps=fps, bitrate=2000) # don't need a very high bitrate def animate(frame): print(frame, frames, frame / frames) ax.azim = 360 * frame / frames # one full rotation return [ ] # must return the list of artists we modified (i.e., nothing, since all we did is rotate the view) ani = anim.FuncAnimation(fig, animate, frames=frames, blit=True) ani.save(f"{os.path.join(kwargs['target_dir'], kwargs['name'])}.mp4", writer=writer) plt.close()
def main(): # Parse arguments parser = argparse.ArgumentParser() parser.add_argument('-c', '--chanrange', nargs=2, type=int, help='Channel range') parser.add_argument('--blc', nargs=2, type=int, help='Bottom left corner of the data box') parser.add_argument('--trc', nargs=2, type=int, help='Top right corner of the data box') parser.add_argument('--xcoverage', default=0.8, type=float, help='Coverage of the spectrum range over each pixel') parser.add_argument('--level', default=None, type=float, help='Ignore spectra below level') parser.add_argument('--mask', default=None, type=float, help='Read a mask from FITS file') parser.add_argument('--every', type=int, default=None, help='Select one pixel every n pixels from peak') parser.add_argument('--autolimit', action='store_true', help='Use std and mean to determine if spectra will be plot') parser.add_argument('--nsigma', type=int, default=3, help='Use std and mean to determine if spectra will be plot') parser.add_argument('--color', default='k', help='Line color') parser.add_argument('cube', type=str, help='FITS cube file name') parser.add_argument('out', type=str, help='Output plot file name') args = parser.parse_args() # Open cube cube = fits.open(os.path.expanduser(args.cube))[0] # Select data npix, x0, x1, y0, y1 = select_data(cube.shape, blc=args.blc, trc=args.trc) if args.chanrange: lenspec = abs(args.chanrange[1]-args.chanrange[0]) + 1 s0, s1 = args.chanrange[0], args.chanrange[1]+1 else: lenspec = cube.shape[-3] s0, s1 = 0, lenspec subcube = cube.data[0, s0:s1, y0:y1, x0:x1] # Create mask if args.mask: mask = fits.open(args.mask)[0] mask = np.squeeze(mask.data).astype(bool) elif args.level: mask = np.any(subcube > args.level, axis=0) elif args.autolimit: mean = np.mean(subcube) std = np.std(subcube) mask = np.any(subcube>mean+args.nsigma*std, axis=0) | \ np.any(subcube<mean-args.nsigma*std, axis=0) else: mask = np.ones(subcube.shape[1:], dtype=bool) if args.every: maxmap = np.nanmax(subcube, axis=0) ymax, xmax = np.unravel_index(np.nanargmax(maxmap), maxmap.shape) mask = mask & mask_every(subcube.shape[1:], args.every, row=ymax, col=xmax) # Data scaling scaling = 1.01*np.nanmax(subcube) xempty = (1. - args.xcoverage)*0.5 xaxis = np.linspace(xempty,1.-xempty, lenspec) # Create figure fig, ax = get_figure(npix, alpha=True) # Limits ax.set_xlim(0, npix) ax.set_ylim(-0.5, npix-0.5) # Plot for y, x in np.transpose(np.nonzero(mask)): # Spectrum spec = subcube[:, y, x] if np.any(np.isnan(spec)): continue # X axis wlg = xaxis+x # Plot ax.plot(wlg, spec/scaling+y, '%s-' % args.color, lw=0.05) fig.savefig(args.out, dpi=600)