def plot_clouds_trisurf(file): with nc(file, 'r') as nc_file: qn_map = np.array(nc_file['QN'][:]).swapaxes(0, 2)[:, :, :180] mcl = measure.marching_cubes_lewiner verts, faces, _, _ = mcl(qn_map, level=1e-3, allow_degenerate=False, step_size=4) fig = plt.figure(1, figsize=(20, 6), tight_layout=True) fig.clf() sns.set_context('paper') sns.set_style( 'ticks', { 'axes.grid': False, 'axes.linewidth': '0.75', 'grid.color': '0.75', 'grid.linestyle': u':', 'legend.frameon': True, }) plt.rc('text', usetex=True) plt.rc('font', family='Serif') ax = fig.add_subplot(111, projection='3d') ax.set_xlabel(r'x') ax.set_ylabel(r'y') ax.set_zlabel(r'z') cmap = sns.diverging_palette(220, 20, n=7, as_cmap=True) ax.plot_trisurf(verts[:, 0], verts[:, 1], faces, verts[:, 2], cmap=cmap, edgecolor='k', lw=0.2) def animate(ii): ax.azim = ii animated_field = anima.FuncAnimation( fig, animate, frames=180, interval=15, ) writer = anima.ImageMagickWriter(fps=15, bitrate=6400, codec="libx264") animated_field.save('animated_field.mp4', writer=writer)
def start_animation(self, file_type, fps, duration, filename): frames = fps * duration if file_type else None interval = 1000 / fps if file_type: # annoyingly required as file animations don't respect the interval set in FuncAnimation, so the balls # bounce around at sanic speed at high fps. factor = 60 / fps for ball in self.balls: ball.v *= factor anim = animation.FuncAnimation( self.fig, self.update_fig, frames=frames, interval=interval, fargs=(5,) ) if file_type == 'gif': anim.save( f'{filename}.gif', animation.ImageMagickWriter(fps=fps, extra_args=['-layers', 'Optimize']) ) elif file_type == 'mp4': anim.save(f'{filename}.mp4', animation.FFMpegWriter(fps=fps)) else: plt.show()
def plot_gen_score(original, gens, scores, dst_path): fig = plt.figure(figsize=(10, 3)) ims = [] for i, g in enumerate(gens): plt.subplot(1, 3, 1) plt.xticks([]) plt.yticks([]) im1 = plt.imshow(np.squeeze(original), vmin=-1., vmax=1., cmap='gray') plt.subplot(1, 3, 2) plt.xticks([]) plt.yticks([]) im2 = plt.imshow(g, vmin=-1., vmax=1., cmap='gray') ax = plt.subplot(1, 3, 3) im3, = plt.plot(np.arange(i + 1), scores[:i + 1], c=red) ax.yaxis.tick_right() ims.append([im1, im2, im3]) writer = animation.ImageMagickWriter() ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=10000) ani.save(dst_path, writer=writer)
import numpy as np import netCDF4 as nc import matplotlib.pyplot as plt import matplotlib.animation as ani from matplotlib import cm # from input_parameters import rhoat, rhooc, fnot import utils as utils datapath = '/rds/general/user/rk2014/home/WORK/q-gcm/outdata_toptest/2/' writer = ani.ImageMagickWriter() # Files that describe oceanic and atmospheric state atast = nc.Dataset(datapath + 'atast.nc') ocsst = nc.Dataset(datapath + 'ocsst.nc') ast = atast.variables['ast'] sst = ocsst.variables['sst'] time = ast.shape[0] # total time for i in range(2): if i == 0: ast = utils.ContourData(ast[:, :, :]) [fig, ax] = ast.init_frame('AST ($K$)', False) anim = ani.FuncAnimation(fig, ast.frame_i, frames=time) anim.save('./ast_b.gif', writer=writer) else: sst = utils.ContourData(sst[:, :, :]) [fig, ax] = sst.init_frame('SST ($K$)', True) anim = ani.FuncAnimation(fig, sst.frame_i, frames=time) anim.save('./sst_b.gif', writer=writer)
class ABCTriangle: def __init__(self, v1, v2, v3): self.v1 = v1 self.v2 = v2 self.v3 = v3 def getXYcoords(self): return [ABCtoXY(self.v1), ABCtoXY(self.v2), ABCtoXY(self.v3)] fig, ax = plt.subplots() plt.xlim(-1, 1) plt.ylim(-0.5, 1.5) writer = manimation.ImageMagickWriter(fps=1) writer.setup(fig, "video.gif", 500) T0 = ABCTriangle([1, 0, 0], [0, 1, 0], [0, 0, 1]) ax.add_patch(plt.Polygon(T0.getXYcoords(), True, color='black')) #ax.set_aspect("equal") T = ABCTriangle([1. / 2., 1. / 2., 0], [1. / 2., 0, 1. / 2.], [0, 1. / 2., 1. / 2.]) ax.add_patch(plt.Polygon(T.getXYcoords(), True, color='white')) prevTriangles = [] prevTriangles.append(T) plt.title("k = 0") writer.grab_frame() for k in range(N): plt.title("k = %i" % (k + 1))
line2.set_offsets(np.array([np.arange(0,num*opt.interv)*0.002403846,A[:,1][:num*opt.interv]]).T) # line2.set_color(c=yhat[:num*opt.interv:opt.interv]) line3.set_offsets(np.array([np.arange(0,num*opt.interv)*0.002403846,A[:,2][:num*opt.interv]]).T) # line3.set_color(c=yhat[:num*opt.interv:opt.interv]) return line1,line2,line3 if opt.animate: #A.shape[0]//opt.interv ani = animation.FuncAnimation(fig, update, A.shape[0]//opt.interv, fargs=[line1,line2,line3], interval=1, blit=True)#, save_count=50) # Writer = animation.writers['ffmpeg_file'] # writer = Writer(fps=60, bitrate=100) # writer = animation.FFMpegWriter(fps=600, metadata=dict(artist='Me'), bitrate=100) writer = animation.ImageMagickWriter(fps=1000) if opt.pillow: Writer = animation.writers['pillow'] # writer = Writer(fps=60, metadata=dict(artist='Me'), bitrate=100) ani.save('./accelerometer.gif', writer=writer) t2 = time() print('Time Elapsed:',(t2 - t1)/60,'minutes') # try: send_sms() # user = '******' # pwd = 'Shoogiebaba23'
# first set up the figure, the axis, and the plot element we want to animate fig = plt.figure() ax = plt.axes(xlim=(0, 2), ylim=(-2, 2)) line, = ax.plot([], [], lw=2) # initialization function: plot the background of each frame def init(): line.set_data([], []) return line, # animation function. this is called sequentially def animate(i): x = np.linspace(0, 2, 1000) y = np.sin(2 * np.pi * (x - 0.01 * i)) line.set_data(x, y) return line, # call the animator. blit=true means only re-draw the parts that have changed. anim = animation.FuncAnimation(fig, animate, init_func=init, frames=200, interval=20, blit=True) # anim.save(".\my.html", writer="imagemagick", fps=2,dpi=20) anim.save("./a.gif", writer=animation.ImageMagickWriter()) plt.show()
plt.close() fx = lambda x : x * x dfx = lambda x : 2 * x grad = GradientDescent(dfx) grad.go(startx=np.array([0.8]), alpha=0.2, eps=0.001) xx = np.linspace(-1, 1, 100, dtype=np.float) yy = fx(xx) gxx = np.array(grad.xs_path) gyy = fx(gxx) size = len(gxx) fig = plt.figure("grand") fig.canvas.mpl_connect('key_press_event', on_key) ax = fig.add_subplot(111) ax.plot(xx, yy, '-b') line = [] def update(n): if n == 0: line.extend(ax.plot(gxx[0], gyy[0], '*r', linewidth=1, markersize=5)) else: line.extend(ax.plot(gxx[n-1:n+1], gyy[n-1:n+1], '*-r', linewidth=1, markersize=5)) return line anim = animation.FuncAnimation(fig, func=update, frames=size, interval=300) anim.save('grad.gif', writer=animation.ImageMagickWriter(fps=5)) plt.show()
def pyview(argv): path = "data/" print('Welcome to PPDyn Visualization Toolkit') # parser = argparse.ArgumentParser(description='PPDyn Visualization Toolkit') # parser.add_argument('-p','--part', default='particle', type=str, help='data type particle') # parser.add_argument('-v','--view', action='store_true', help='Show Animation') # parser.add_argument('-s','--save', action='store_false', help='Save Animation') # args = parser.parse_args() # data = args.part # show_anim = args.view # save_anim = args.save inputFile = argv data = 'particle' params = ini.parse(open(argv).read()) show_anim = bool(params['animate']['show_anim']) save_anim = bool(params['animate']['save_anim']) interval = 0.001 #in seconds h5 = h5py.File('data/' + data + '.hdf5', 'r') Lx = h5.attrs["Lx"] Ly = h5.attrs["Ly"] Lz = h5.attrs["Lz"] dp = h5.attrs["dp"] Nt = h5.attrs["Nt"] data_num = np.arange(start=0, stop=Nt, step=dp, dtype=int) if (show_anim == True): def animate(i): # file=path+'/data%d'%data_num[i]+'.dat' datax = h5["/%d" % data_num[i] + "/position/x"] datay = h5["/%d" % data_num[i] + "/position/y"] dataz = h5["/%d" % data_num[i] + "/position/z"] ax1.cla() img1 = ax1.scatter(datax, datay, dataz, marker='o', color='b', alpha=1.0, s=10) ax1.set_title('TimeSteps = %d' % i + '\n Phase Space') ax1.set_xlabel("$x$") ax1.set_ylabel("$y$") ax1.set_xlim([-Lx, Lx]) ax1.set_ylim([-Ly, Ly]) ax1.set_ylim([-Lz, Lz]) if (show_anim == True): # fig,ax1 = plt.subplots(1,1,1, projection='3d') fig = plt.figure(figsize=(6, 6)) ax1 = plt.axes(projection="3d") ani = animation.FuncAnimation(fig, animate, frames=len(data_num), interval=interval * 1e+3, blit=False) # ani.save('phase_space.gif',writer='imagemagick') plt.show() if (save_anim == True): try: Writer = animation.writers['ffmpeg'] writer = Writer(fps=(1 / interval), metadata=dict(artist='Me'), bitrate=1800) except RuntimeError: print("ffmpeg not available trying ImageMagickWriter") writer = animation.ImageMagickWriter(fps=(1 / interval)) ani.save('mdanimation3d.mp4') if show_anim == False and show_anim == False: print("You have not opted for showing or saving animation.") print("End of animation")
def save(self): self.ani.save('/tmp/output.gif', writer=animation.ImageMagickWriter(fps=10))
ax.set_xlabel('Iteration %i' % i) for key in coords_dict: coords = transformation.transform(coords_dict[key], T_iter[i][key]) artists[key].set_data(coords[:, 0], coords[:, 1]) artists[key].set_3d_properties(coords[:, 2]) return artists.values() # creates the animation anim = animation.FuncAnimation(fig, animate, frames=range(len(T_iter)), interval=250, blit=True) # save as GIF anim.save('nicp.gif', writer=animation.ImageMagickWriter()) plt.close() # display as HTML (online version only) HTML(anim.to_jshtml()) # ## References # [1] P.J. Besl and N.D. McKay (1992): 'A Method for Registration of 3-D Shapes', IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 14 (2): 239-256. # # [2] Stanford University Computer Graphics Laboratory, (1993): 'Stanford Bunny', URL [https://graphics.stanford.edu/data/3Dscanrep/](https://graphics.stanford.edu/data/3Dscanrep/) # (accessed January 17, 2019). # # [3] J. Serafin and G. Grisetti (2014): 'Using augmented measurements to improve the convergence of icp', International Conference on Simulation, Modeling, and Programming for Autonomous Robots. Springer, Cham: 566-577. # # [4] J. Serafin and G. Grisetti (2014): 'NICP: Dense normal based pointcloud registration', International Conference on Intelligent Robots and Systems (IROS): 742-749.
return (fig, ax) def saddle_3d_animation(): optimizers, methods = get_saddle_optimizers(d_func=saddle_d_func) paths = [np.array(optimizer.get_params_history(np.array([-0.5, -1e-4]), 300)).T for optimizer in optimizers] z_paths = [saddle_func(path) for path in paths] fig, ax = saddle_3d_plot() return TrajectoryAnimation3D(*paths, z_paths=z_paths, labels=methods, ax=ax, steps=1) if __name__ == '__main__': gif_writer = animation.ImageMagickWriter(fps=60) mp4_writer = animation.FFMpegWriter(fps=60, bitrate=1800, metadata=dict(artist='Mr. Black')) beales_2d_plt, _ = beales_2d_plot() beales_2d_plt.show() beales_2d_anim = beales_2d_animation() beales_2d_anim.ax.legend(loc='upper left', fontsize='xx-large') beales_2d_anim.save('beales-2d-anim.gif', writer=gif_writer) beales_2d_anim.save('beales-2d-anim.mp4', writer=mp4_writer) beales_3d_plt, _ = beales_3d_plot() beales_3d_plt.show() beales_3d_anim = beales_3d_animation() beales_3d_anim.ax.legend(loc='upper left', fontsize='xx-large') beales_3d_anim.save('beales-3d-anim.gif', writer=gif_writer) beales_3d_anim.save('beales-3d-anim.mp4', writer=mp4_writer)
def create_movie(self, filename, use_frames=True, integral_x=False, integral_y=False, fps=1.0, fading=False, subframes=10, dpi=100, writer_name="libav"): """ Creates and saves a movie from the frames. Args: filename (string): name of the movie use_frames (bool): put the frame image in the movie integral_x (bool): put the frame horizontal integral in the movie integral_y (bool): put the frame vertical integral in the movie fps (float): frame per second speed fading (bool): set the fading on/off between frames subframes (int): if the fading is active, each frame is divided into this number of subframes, and the transition will use 3 frames (min 3) dpi (float): resolution of the movie (max 200) writer_name (string): name of a valid movie writer (see the code forlibav, ffmpeg, imagemagick) """ #check if plot can be done if not (use_frames or integral_x or integral_y): print "Error: nothing to plot in the video" return if not use_frames and integral_x and integral_y: print "Error: wrong movie elements selections" return #frame figure width in inches inch_size = 5.0 #number of subrames (that must be > 3 for the fading) subframes = int(max(subframes, 4)) #avoid too big resolution that would crash the cpu dpi = float(min(dpi, 200)) #get an initial frame, and the dimension from the main slices frame = self.frames[self.valid_frames_id[0]] frame_h, frame_w = frame[self.main_slices].shape frame_ratio = float(frame_h) / float(frame_w) #calculate the movie size according to what must be plotted if use_frames: fig_size = [inch_size, inch_size * frame_ratio] if integral_x: fig_size[1] = fig_size[1] + inch_size / 2.0 if integral_y: fig_size[0] = fig_size[0] + inch_size / 2.0 elif integral_x: fig_size = [inch_size, inch_size / 2.0] elif integral_y: fig_size = [inch_size / 2.0, inch_size] plt.rcParams['figure.figsize'] = fig_size metadata = dict(title='Atom Movie', artist='Matplotlib', comment='Video of ultracold gases') if fading: #if fading is active the fps must be multiplied for the subframes fps_real = float(fps) * subframes else: subframes = 1 fps_real = float(fps) #initialize the writer if writer_name == "ffmpeg": writer = animation.FFMpegWriter(fps=float(fps_real), metadata=metadata) elif writer_name == "libav": writer = animation.AVConvWriter(fps=float(fps_real), metadata=metadata) elif writer_name == "imagemagick": writer = animation.ImageMagickWriter(fps=float(fps_real), metadata=metadata) else: print "Error, movie writer not supported." print "Supported writers: libav, ffmpeg, imagemagick" return #TODO: check GIF first frame colors #initialize figure and axes fig = plt.figure() ax1 = None #frame axe axx = None #horizontal integral axe axy = None #vertical integral axe if integral_x and not integral_y and not use_frames: axx = plt.subplot2grid((1, 1), (0, 0)) elif not integral_x and integral_y and not use_frames: axy = plt.subplot2grid((1, 1), (0, 0)) elif integral_x and not integral_y and use_frames: ax1 = plt.subplot2grid((3, 1), (0, 0), rowspan=2) axx = plt.subplot2grid((3, 1), (2, 0), sharex=ax1) elif not integral_x and integral_y and use_frames: ax1 = plt.subplot2grid((1, 3), (0, 1), colspan=2) axy = plt.subplot2grid((1, 3), (0, 0), sharey=ax1) elif integral_x and integral_y and use_frames: ax1 = plt.subplot2grid((3, 3), (0, 1), rowspan=2, colspan=2) axx = plt.subplot2grid((3, 3), (2, 1), colspan=2, sharex=ax1) axy = plt.subplot2grid((3, 3), (0, 0), rowspan=2, sharey=ax1) elif not integral_x and not integral_y and use_frames: ax1 = plt.subplot2grid((1, 1), (0, 0)) #TODO control better space between subplots fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=None, hspace=None) fig.tight_layout(pad=0.1) def get_frame(frames, n_frame, n_subfr): """ Calculates and returns the frame given the current frame id. """ if n_subfr < subframes - 3 or not fading: #if the subframes are at the beginning or the fading is off frame = frames[n_frame] else: #id of the next frame (ciclical) if n_frame == self.valid_frames_id[-1]: n_frame_next = self.valid_frames_id[0] else: n_frame_next = n_frame + 1 #basic fading algoritm between frames if n_subfr == subframes - 3: frame = 0.75 * frames[n_frame] + 0.25 * frames[n_frame_next] elif n_subfr == subframes - 2: frame = 0.5 * frames[n_frame] + 0.5 * frames[n_frame_next] elif n_subfr == subframes - 1: frame = 0.25 * frames[n_frame] + 0.75 * frames[n_frame_next] return frame def calc_x_int(frame): """ Calculate the horizontal integral of a frame. Returns the coordinates and the normalized integral. Args: frame (np.array): frame to integrate """ x_int = np.sum(frame[self.main_slices], axis=0) #indices of the main and max selection ind_main = self.main_slices[1].indices(frame.shape[1]) ind_max = self.maximum_slices[1].indices(frame.shape[1]) #slices of the frame that will be used to calculate the #normalization of the integral norm_slice = [ self.main_slices[0], slice(max(ind_main[0], ind_max[0]), min(ind_main[1], ind_max[1])) ] norm = np.mean(np.sum(frame[norm_slice], axis=0)) return np.arange(frame_w), x_int / norm def calc_y_int(frame): """ Calculate the vertical integral of a frame. Returns the normalized integral and the coordinates. Args: frame (np.array): frame to integrate """ y_int = np.sum(frame[self.main_slices], axis=1) ind_main = self.main_slices[0].indices(frame.shape[0]) ind_max = self.maximum_slices[0].indices(frame.shape[0]) norm_slice = [ slice(max(ind_main[0], ind_max[0]), min(ind_main[1], ind_max[1])), self.main_slices[1] ] norm = np.mean(np.sum(frame[norm_slice], axis=1)) return y_int / norm, np.arange(frame_h) #create initial plots if use_frames: ax1_plot = ax1.imshow(frame[self.main_slices], vmin=self.get_vlim_img()[0], vmax=self.get_vlim_img()[1], aspect='auto') ax1.axis("off") ax1_plot.set_cmap(self.cmap_img) if integral_x: axx_plot, = axx.plot(*calc_x_int(frame), lw=4) axx.axis("off") axx.set_xlim(0, frame_w) axx.set_ylim(-0.05, 1.1) if integral_y: axy_plot, = axy.plot(*calc_y_int(frame), lw=4) axy.axis("off") axy.set_ylim(0, frame_h) axy.set_xlim(-0.05, 1.1) #reconstruct frames from the total image (this is done in order #to include in the viedeo all effect applied to the final image) frames = [] for n_frame in range(self.frame_num): row = int(n_frame / self.frame_cols) col = int(n_frame % self.frame_cols) frm = self.all_frames_img[row * self.frame_h:(row + 1) * self.frame_h, col * self.frame_w:(col + 1) * self.frame_w] frames.append(frm) frames = np.array(frames) #write the movie from the figure with writer.saving(fig, str(filename), dpi): #iterate over frames and subframes for n_frame in self.valid_frames_id: for n_subfr in range(subframes): frame = get_frame(frames, n_frame, n_subfr) #update plot data and grab instead of pltting again #for efficiency if use_frames: ax1_plot.set_data(frame[self.main_slices]) if integral_x: axx_plot.set_data(*calc_x_int(frame)) if integral_y: axy_plot.set_data(*calc_y_int(frame)) writer.grab_frame()
if (show_anim == True): def animate(i): file=DIR+'/data%d'%data_num[i]+'.txt' datax,datay,dataz = np.loadtxt(file, unpack=True) ax1.cla() img1 = ax1.scatter(datax,datay,dataz,marker='o',color='b',alpha=1.0,s=10) ax1.set_title('TimeSteps = %d'%i+'\n Phase Space') ax1.set_xlabel("$x$") ax1.set_ylabel("$y$") ax1.set_xlim([-Lx, Lx]) ax1.set_ylim([-Ly, Ly]) ax1.set_ylim([-Lz, Lz]) if (show_anim == True): # fig,ax1 = plt.subplots(1,1,1, projection='3d') fig = plt.figure(figsize=(6, 6)) ax1 = plt.axes(projection ="3d") ani = animation.FuncAnimation(fig,animate,frames=len(data_num),interval=interval*1e+3,blit=False) # ani.save('phase_space.gif',writer='imagemagick') plt.show() if(save_anim == True): try: Writer = animation.writers['ffmpeg'] writer = Writer(fps=(1/interval), metadata=dict(artist='Me'), bitrate=1800) except RuntimeError: print("ffmpeg not available trying ImageMagickWriter") writer = animation.ImageMagickWriter(fps=(1/interval)) ani.save('animation.mp4')
fps = 20 interval = 1000.0 / float(fps) # in ms # FuncAnimation will call the update() function for each frame: print "Creating animation..." anim = mplanim.FuncAnimation(fig, update, frames=np.arange(0, 360), interval=interval, blit=False) # Set up the animation writing function, # here using the ImageMagickWriter. # This pipes the frames straight to ImageMagick to create a gif: writer = mplanim.ImageMagickWriter(fps=fps) # https://matplotlib.org/api/_as_gen/matplotlib.animation.ImageMagickWriter.html # Alternatives are the ImageMagickFileWriter(), # which saves out each frame before calling ImageMagick convert: # https://matplotlib.org/api/_as_gen/matplotlib.animation.ImageMagickFileWriter.html # and FFMpegWriter, FFMpegFileWriter equivalently: # https://matplotlib.org/api/_as_gen/matplotlib.animation.FFMpegWriter.html # https://matplotlib.org/api/_as_gen/matplotlib.animation.FFMpegFileWriter.html # Finally, save using that writer: # (this is the stage when it is actually generated, # and takes time - about 40 mins on my laptop!) print "About to save animation:" anim.save('animated_globe.gif', dpi=96, writer=writer)
def main(): params = ini.parse(open('input.ini').read()) # Input parameters directory = str(params['fileHierarchy']['directory']) inDir = str(params['fileHierarchy']['inDir']) outDir = str(params['fileHierarchy']['outDir']) imgDir = str(params['fileHierarchy']['imgDir']) contDir = str(params['fileHierarchy']['contDir']) fstart = int(params['fileSequence']['start']) fend = int(params['fileSequence']['end']) dt = int(params['fileSequence']['interval']) thresholdDensity = float(params['contourParams']['threshold']) show_anim = bool(params['animation']['show']) save_anim = bool(params['animation']['save']) fps = float(params['animation']['fps']) INDIR =directory+"/"+inDir+"/" OUTDIR =directory+"/"+outDir+"/" IMGDIR =directory+"/"+outDir+"/"+imgDir+"/" CONTDIR =directory+"/"+outDir+"/"+contDir+"/" print("===========File Hierarchy===========") print("Raw data directory: "+INDIR) print("Processed Blob property data directory: "+OUTDIR) print("Blob images directory: "+IMGDIR) print("Blob contour data directory: "+CONTDIR) #========== Blob Data Directory Setup ============= if os.path.exists(directory): if os.path.exists(OUTDIR): os.system('rm '+OUTDIR+"*.txt 2>/dev/null") if os.path.exists(IMGDIR) and os.path.exists(CONTDIR): os.system('rm '+IMGDIR+"* 2>/dev/null") os.system('rm '+CONTDIR+"* 2>/dev/null") else: os.system('mkdir '+IMGDIR) os.system('mkdir '+CONTDIR) else: os.system('mkdir '+OUTDIR) os.system('mkdir '+IMGDIR) os.system('mkdir '+CONTDIR) else: os.system('mkdir '+directory) os.system('mkdir '+OUTDIR) os.system('mkdir '+IMGDIR) os.system('mkdir '+CONTDIR) ############################################ data_num = np.arange(start=fstart, stop=fend, step=dt, dtype=int) f = ad.file(INDIR+'asdex_phi_%d'%data_num[0]+'.bp') blob_size_file = open(OUTDIR+"/blob_size.txt", "w") Nx = f['numCells'][0] Ny = f['numCells'][1] Nz = f['numCells'][2] Xmin = f['lowerBounds'][0] Ymin = f['lowerBounds'][1] Zmin = f['lowerBounds'][2] Xmax = f['upperBounds'][0] Ymax = f['upperBounds'][1] Zmax = f['upperBounds'][2] dx = (Xmax - Xmin) / Nx dy = (Ymax - Ymin) / Ny z_slice = 10 cnum = 100 cnumout = 30 color = 'jet' ################### INTERPOLATION ########################### def interpTestPoint(xWeight,yWeight,dx,dy,probeDensity): testDensity00 = probeDensity[0,0] * (dx-xWeight) * (dy-yWeight) testDensity01 = probeDensity[0,1] * xWeight * (dy-yWeight) testDensity10 = probeDensity[1,0] * (dx-xWeight) * yWeight testDensity11 = probeDensity[1,1] * xWeight * yWeight testDensity = ( testDensity00 + testDensity01 + testDensity10 + testDensity11 ) / (dx*dy) return testDensity ################### Shoelace formula to find polygon Area ########################### def PolyArea(x,y): return 0.5*np.abs(np.dot(x,np.roll(y,1))-np.dot(y,np.roll(x,1))) #################################################################################### #################### RAY TRACING ALGORITHM ######################################### #################################################################################### # A Python3 program to check if a given point lies inside a given polygon # Refer https://www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/ # for explanation of functions onSegment(), orientation() and doIntersect() # Define Infinite (Using INT_MAX caused overflow problems) INF = 10000 class Point: def __init__(self, x, y): self.x = x self.y = y # Given three colinear points p, q, r, the function checks if # point q lies on line segment 'pr' def onSegment(p, q, r): if ( (q.x <= max(p.x, r.x)) and (q.x >= min(p.x, r.x)) and (q.y <= max(p.y, r.y)) and (q.y >= min(p.y, r.y))): return True return False def orientation(p, q, r): # to find the orientation of an ordered triplet (p,q,r) # function returns the following values: # 0 : Colinear points # 1 : Clockwise points # 2 : Counterclockwise # See https://www.geeksforgeeks.org/orientation-3-ordered-points/amp/ # for details of below formula. val = (float(q.y - p.y) * (r.x - q.x)) - (float(q.x - p.x) * (r.y - q.y)) if (val > 0): # Clockwise orientation return 1 elif (val < 0): # Counterclockwise orientation return 2 else: # Colinear orientation return 0 # The main function that returns true if # the line segment 'p1q1' and 'p2q2' intersect. def doIntersect(p1,q1,p2,q2): # Find the 4 orientations required for # the general and special cases o1 = orientation(p1, q1, p2) o2 = orientation(p1, q1, q2) o3 = orientation(p2, q2, p1) o4 = orientation(p2, q2, q1) # General case if ((o1 != o2) and (o3 != o4)): return True # Special Cases # p1 , q1 and p2 are colinear and p2 lies on segment p1q1 if ((o1 == 0) and onSegment(p1, p2, q1)): return True # p1 , q1 and q2 are colinear and q2 lies on segment p1q1 if ((o2 == 0) and onSegment(p1, q2, q1)): return True # p2 , q2 and p1 are colinear and p1 lies on segment p2q2 if ((o3 == 0) and onSegment(p2, p1, q2)): return True # p2 , q2 and q1 are colinear and q1 lies on segment p2q2 if ((o4 == 0) and onSegment(p2, q1, q2)): return True # If none of the cases return False # Returns true if the point p lies inside the polygon[] with n vertices def isInside(polygon, n, p): # There must be at least 3 vertices in polygon[] if (n < 3): return False # Create a point for line segment from p to infinite extreme = Point(INF, p.y) # Count intersections of the above line with sides of polygon count = 0 i = 0 # To initialize i for the first iteration of do-while loop of C++ type next = (i+1)%n # Check if the line segment from 'p' to 'extreme' intersects # with the line segment from 'polygon[i]' to 'polygon[next]' if (doIntersect(polygon[i], polygon[next], p, extreme)): # If the point 'p' is colinear with line segment 'i-next', # then check if it lies on segment. If it lies, return true, # otherwise false if (orientation(polygon[i], p, polygon[next]) == 0): return onSegment(polygon[i], p, polygon[next]) count = count + 1 i = next while (i != 0): next = (i+1)%n # Check if the line segment from 'p' to 'extreme' intersects # with the line segment from 'polygon[i]' to 'polygon[next]' if (doIntersect(polygon[i], polygon[next], p, extreme)): # If the point 'p' is colinear with line segment 'i-next', # then check if it lies on segment. If it lies, return true, # otherwise false if (orientation(polygon[i], p, polygon[next]) == 0): return onSegment(polygon[i], p, polygon[next]) count = count + 1 i = next if (i == 0): break # Return true if count is odd, false otherwise if (count%2 == 1): return True else: return False #################################################################################### #################################################################################### #################################################################################### def func_data(ionDensityData,phiData): ionDensityInterp = pg.data.GInterpModal(ionDensityData, 1, 'ms') phiInterp = pg.data.GInterpModal(phiData, 1, 'ms') interpGrid, ionDensityValues = ionDensityInterp.interpolate() interpGrid, phiValues = phiInterp.interpolate() #exValues = - np.gradient(phiValues,dx,axis = 0) #dexdxValues = np.gradient(exValues,dx,axis = 0) eyValues = - np.gradient(phiValues,dy,axis = 1) # get cell center coordinates CCC = [] for j in range(0,len(interpGrid)): CCC.append((interpGrid[j][1:] + interpGrid[j][:-1])/2) x_vals = CCC[0] y_vals = CCC[1] z_vals = CCC[2] X, Y = np.meshgrid(x_vals, y_vals) ionDensityGrid = np.transpose(ionDensityValues[:,:,z_slice,0]) eyGrid = np.transpose(eyValues[:,:,z_slice,0]) return x_vals,y_vals,X,Y,ionDensityGrid,eyGrid def animate(i): blob_counter = 0 ionDensity=INDIR+'asdex_ion_GkM0_%d'%data_num[i]+'.bp' phi=INDIR+'asdex_phi_%d'%data_num[i]+'.bp' ionDensityData = pg.data.GData(ionDensity) phiData = pg.data.GData(phi) x_vals,y_vals,X,Y,ionDensityGrid,eyGrid = func_data(ionDensityData,phiData) Nx = len(x_vals) Ny = len(y_vals) ax1.cla() ax1.set_title('Time = %d'%i+' $\\mu$s') cp1 = ax1.contourf(X, Y, ionDensityGrid, cnum, cmap=color) #cp2 = ax1.contour(X, Y, eyGrid, cnum, linewidths=0.1, colors='black', linestyles='solid') cp3 = ax1.contour(X, Y, ionDensityGrid, cnumout, linewidths=0.1, colors='black', linestyles='solid') #cp3 = ax1.contour(X, Y, ionDensityGrid, cnumout, linewidths=1, cmap=color) cp4 = ax1.contour(X, Y, ionDensityGrid, [thresholdDensity], linewidths=1, colors='black', linestyles='solid') # #plt.grid() # ax1.set_xticks(x_vals , minor=True) # ax1.set_yticks(y_vals , minor=True) # #ax1.grid(which='both') # ax1.grid(which='minor', alpha=0.9, color='k', linestyle='-') p = cp4.collections[0].get_paths() contour_number = len(p) imageCounter = 0 for j in range(contour_number): p_new = cp4.collections[0].get_paths()[j] v = p_new.vertices x = v[:,0] y = v[:,1] x_min = np.min(x) x_max = np.max(x) y_min = np.min(y) y_max = np.max(y) blobMidX = (x_min + x_max)/2 blobMidY = (y_min + y_max)/2 blobLimX = abs(x_max - x_min) blobLimY = abs(y_max - y_min) if (abs(x[0]-x[len(x)-1]) <= 1e-10) and blobLimX > 2*dx and blobLimY > 2*dy: polygon = [] for plgn in range(len(x)): polygon.append(Point(x[plgn],y[plgn])) npoly = len(polygon) numTrial = 100 blobConfidence = 0 insideTrialPoints = 0 for numT in range(numTrial): xT = 0.5*(x_max+x_min) - 0.5*(x_max-x_min)*(random()-0.5) yT = 0.5*(y_max+y_min) - 0.5*(y_max-y_min)*(random()-0.5) #print("Trial point",numT,"with",round(xT,4),round(yT,4),'for contour number %d'%j) trialPoint = Point(xT,yT) if isInside(polygon, npoly, trialPoint): insideTrialPoints = insideTrialPoints + 1 #print("Trial point", numT, "is INSIDE for contour number %d"%j) xd = abs(x_vals-xT) yd = abs(y_vals-yT) idx = np.where(xd <= 0.5*dx) idy = np.where(yd <= 0.5*dy) ionDensityFind = np.reshape(ionDensityGrid,Nx*Ny) probeDensity = np.zeros((2,2)) for id in range(len(idx[0])): for jd in range(len(idy[0])): probeDensity[id,jd] = ionDensityFind[(idy[0][jd] * Nx) + (idx[0][id] + 1)] xGrid = np.zeros(2) yGrid = np.zeros(2) for id in range(len(idx[0])): xGrid[id] = x_vals[idx[0][id]] for jd in range(len(idy[0])): yGrid[jd] = y_vals[idy[0][jd]] xWeight = abs(xGrid[0]-xT) yWeight = abs(yGrid[0]-yT) testDensity = interpTestPoint(xWeight,yWeight,dx,dy,probeDensity) if (testDensity >= thresholdDensity): #print("Interpolated point",numT,"with",round(xInterp,4),round(yInterp,4)," for Contour number %d"%j+" is INSIDE & truly a BLOB! Yeyy...") blobConfidence = blobConfidence + 1 else: None else: None #print("Trial point", numT, " lies Outside before interpolation") confidence = blobConfidence/insideTrialPoints #print("Confidence = ",confidence*100,"%") if (confidence > 0.80): blob_counter = blob_counter + 1 polyArea = PolyArea(x,y) #print(polyArea) # print('File number = %d'%data_num[i]+', contour number %d'%j+' = It is TRULY a blob with confidence',confidence*100,"%") blob_size_file.write('%d'%data_num[i]+'\t%d'%j+'\t%.8f'%blobLimX+'\t%.8f'%blobLimY+'\t%.8f'%blobMidX+'\t%.8f'%blobMidY+'\t%.8f'%polyArea+'\n') if imageCounter == 0: plt.savefig(IMGDIR+"/file_number%d"%data_num[i]+"_blob_snap.png") # save the figure to file imageCounter = imageCounter + 1 #print("blobConfidence=",blobConfidence,"insideTrialPoints=",insideTrialPoints) blob_file = open(CONTDIR+"/file_number%d"%data_num[i]+"_contour_number_%d"%j+".txt", "w") for k in range(len(x)): blob_file.write('%.8f'%x[k]+'\t%.8f'%y[k]+'\n') blob_file.close() elif (abs(x[0]-x[len(x)-1]) <= 1e-10): None # print('File number = %d'%data_num[i]+', contour number %d'%j+' = It is a sub-grid-sized closed contour') else: None # print('File number = %d'%data_num[i]+', contour number %d'%j+' = It is open line & NOT a blob') #print(x,y) #for k in range(len(x)): #print(round(x[k],7),round(y[k],7)) if blob_counter == 0: None # print("No blob found for file number = %d"%data_num[i]) sleep(0.1) pbar.update(pstep) #plt.grid(True) ax1.set_xlabel("X",fontsize=14) ax1.set_ylabel("Y",fontsize=14) #ax1.tick_params(axis='both', which='major', labelsize=12) del ionDensityData del phiData if (show_anim == True): fig,ax1 = plt.subplots(1,1,figsize=(8,5),dpi=150) plt.rcParams["font.size"] = "12" plt.rcParams["font.family"] = "Times New Roman" #To keep the colorbar static: ionDensity=INDIR+'asdex_ion_GkM0_%d'%data_num[0]+'.bp' phi=INDIR+'asdex_phi_%d'%data_num[0]+'.bp' ionDensityData = pg.data.GData(ionDensity) phiData = pg.data.GData(phi) x_vals,y_vals,X,Y,ionDensityGrid,eyGrid = func_data(ionDensityData,phiData) cp1 = ax1.contourf(X, Y, ionDensityGrid, cnum, cmap=color) fig.colorbar(cp1) #TColorbar fixing completed: pstep = 1#len(data_num)/100 pbar = tqdm(total=len(data_num)) ani = animation.FuncAnimation(fig,animate,frames=len(data_num),interval=(1/fps)*1e+3,blit=False,repeat=False) ax1.set_xticks(x_vals , minor=True) ax1.set_yticks(y_vals , minor=True) ax1.grid(which='both') ax1.grid(which='minor', alpha=0.2, color='b', linestyle='--') #ax1.grid(b=True, which='major', color='b', linestyle='-') plt.show() if(save_anim == True): try: Writer = animation.writers['ffmpeg'] writer = Writer(fps=fps, metadata=dict(artist='Me'), bitrate=1800) except RuntimeError: print("ffmpeg not available trying ImageMagickWriter") writer = animation.ImageMagickWriter(fps=fps) ani.save('animation.mp4') pbar.close() blob_size_file.close() return 0
def save(self, filename: str) -> None: # there seems to be no way of preventing passing the loop once setting to the saved gif and it loops forever, which is very annoying self.anim.save( filename, dpi=80, writer=animation.ImageMagickWriter(extra_args=["-loop", "1"]))