p1 = fig.add_subplot(121, projection='3d') p2 = fig.add_subplot(122, projection='3d') p1.set_title("U") p2.set_title("V") # movie generations #matplotlib.use("Agg") #FFMpegWriter = anim.writers['ffmpeg'] matplotlib.verbose.level = 'debug' matplotlib.verbose.fileo = sys.stdout metadata = dict(title='"Movie Test"', artist='Matplotlib', comment='"Movie support!"') #writer = FFMpegWriter(fps=15, metadata=metadata) writer = anim.FFMpegFileWriter(fps=15, metadata=metadata) # simulation constants nx = 201 ny = 201 nt = 200 visc = 0.0025 dt = .002 #.0015 #0.0025 #0.01 dx = 2.0 / (nx - 1.0) dy = 2.0 / (ny - 1.0) # for plotting xs = np.linspace(0.0, 2.0, nx) ys = np.linspace(0.0, 2.0, ny) X, Y = np.meshgrid(xs, ys)
def animated_timeseries_WIT( ds, df, output_path, width_pixels=1000, interval=200, bands=["red", "green", "blue"], percentile_stretch=(0.02, 0.98), image_proc_func=None, title=False, show_date=True, annotation_kwargs={}, onebandplot_cbar=True, onebandplot_kwargs={}, shapefile_path=None, shapefile_kwargs={}, pandasplot_kwargs={}, time_dim="time", x_dim="x", y_dim="y", ): ############### # Setup steps # ############### # Test if all dimensions exist in dataset if time_dim in ds and x_dim in ds and y_dim in ds: # Test if there is one or three bands, and that all exist in both datasets: if ((len(bands) == 3) | (len(bands) == 1)) & all([(b in ds.data_vars) for b in bands]): # Import xarrays as lists of three band numpy arrays imagelist, vmin, vmax = _ds_to_arrraylist( ds, bands=bands, time_dim=time_dim, x_dim=x_dim, y_dim=y_dim, percentile_stretch=percentile_stretch, image_proc_func=image_proc_func, ) # Get time, x and y dimensions of dataset and calculate width vs height of plot timesteps = len(ds[time_dim]) width = len(ds[x_dim]) height = len(ds[y_dim]) width_ratio = float(width) / float(height) height = 10.0 / width_ratio # If title is supplied as a string, multiply out to a list with one string per timestep. # Otherwise, use supplied list for plot titles. if isinstance(title, str) or isinstance(title, bool): title_list = [title] * timesteps else: title_list = title # Set up annotation parameters that plt.imshow plotting for single band array images. # The nested dict structure sets default values which can be overwritten/customised by the # manually specified `onebandplot_kwargs` onebandplot_kwargs = dict( { "cmap": "Greys", "interpolation": "bilinear", "vmin": vmin, "vmax": vmax, "tick_colour": "black", "tick_fontsize": 11, }, **onebandplot_kwargs, ) # Use pop to remove the two special tick kwargs from the onebandplot_kwargs dict, and save individually onebandplot_tick_colour = onebandplot_kwargs.pop("tick_colour") onebandplot_tick_fontsize = onebandplot_kwargs.pop("tick_fontsize") # Set up annotation parameters that control font etc. The nested dict structure sets default # values which can be overwritten/customised by the manually specified `annotation_kwargs` annotation_kwargs = dict( { "xy": (1, 1), "xycoords": "axes fraction", "xytext": (-5, -5), "textcoords": "offset points", "horizontalalignment": "right", "verticalalignment": "top", "fontsize": 15, "color": "white", "path_effects": [PathEffects.withStroke(linewidth=3, foreground="black")], }, **annotation_kwargs, ) # Define default plotting parameters for the overlaying shapefile(s). The nested dict structure sets # default values which can be overwritten/customised by the manually specified `shapefile_kwargs` shapefile_kwargs = dict( { "linewidth": 2, "edgecolor": "black", "facecolor": "#00000000" }, **shapefile_kwargs, ) # Define default plotting parameters for the right-hand line plot. The nested dict structure sets # default values which can be overwritten/customised by the manually specified `pandasplot_kwargs` pandasplot_kwargs = dict({}, **pandasplot_kwargs) ################### # Initialise plot # ################### # Set up figure fig, (ax1, ax2) = plt.subplots(ncols=2, gridspec_kw={"width_ratios": [1, 2]}) fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0.2, hspace=0) fig.set_size_inches(10.0, height * 0.5, forward=True) ax1.axis("off") ax2.margins(x=0.01) ax2.xaxis.label.set_visible(False) # Initialise axesimage objects to be updated during animation, setting extent from dims extents = [ float(ds[x_dim].min()), float(ds[x_dim].max()), float(ds[y_dim].min()), float(ds[y_dim].max()), ] im = ax1.imshow(imagelist[0], extent=extents, **onebandplot_kwargs) # Initialise right panel and set y axis limits # set up color palette pal = [ sns.xkcd_rgb["cobalt blue"], sns.xkcd_rgb["neon blue"], sns.xkcd_rgb["grass"], sns.xkcd_rgb["beige"], sns.xkcd_rgb["brown"], ] # make a stacked area plot ax2.stackplot( df.index, df.wofs_area_percent, df.wet_percent, df.green_veg_percent, df.dry_veg_percent, df.bare_soil_percent, labels=[ "open water", "wet", "green veg", "dry veg", "bare soil" ], colors=pal, alpha=0.6, **pandasplot_kwargs, ) ax2.legend(loc="lower left", framealpha=0.6) df1 = pd.DataFrame({ "wofs_area_percent": df.wofs_area_percent, "wet_percent": df.wofs_area_percent + df.wet_percent, "green_veg_percent": df.wofs_area_percent + df.wet_percent + df.green_veg_percent, "dry_veg_percent": df.wofs_area_percent + df.wet_percent + df.green_veg_percent + df.dry_veg_percent, "bare_soil_percent": df.dry_veg_percent + df.green_veg_percent + df.wofs_area_percent + df.wet_percent + df.bare_soil_percent, }) df1 = df1.set_index(df.index) line_test = df1.plot(ax=ax2, legend=False, colors="black", **pandasplot_kwargs) # set axis limits to the min and max ax2.set(xlim=(df.index[0], df.index[-1]), ylim=(0, 100)) # add a legend and a tight plot box ax2.set_title("Fractional Cover, Wetness, and Water") # Initialise annotation objects to be updated during animation t = ax1.annotate("", **annotation_kwargs) ######################### # Add optional overlays # ######################### # Optionally add shapefile overlay(s) from either string path or list of string paths if isinstance(shapefile_path, str): shapefile = gpd.read_file(shapefile_path) shapefile.plot(**shapefile_kwargs, ax=ax1) elif isinstance(shapefile_path, list): # Iterate through list of string paths for shapefile in shapefile_path: shapefile = gpd.read_file(shapefile) shapefile.plot(**shapefile_kwargs, ax=ax1) # After adding shapefile, fix extents of plot ax1.set_xlim(extents[0], extents[1]) ax1.set_ylim(extents[2], extents[3]) # Optionally add colourbar for one band images if (len(bands) == 1) & onebandplot_cbar: _add_colourbar( ax1, im, tick_fontsize=onebandplot_tick_fontsize, tick_colour=onebandplot_tick_colour, vmin=onebandplot_kwargs["vmin"], vmax=onebandplot_kwargs["vmax"], ) ######################################## # Create function to update each frame # ######################################## # Function to update figure def update_figure(frame_i): #################### # Plot image panel # #################### # If possible, extract dates from time dimension try: # Get human-readable date info (e.g. "16 May 1990") ts = ds[time_dim][{time_dim: frame_i}].dt year = ts.year.item() month = ts.month.item() day = ts.day.item() date_string = "{} {} {}".format(day, calendar.month_abbr[month], year) except: date_string = ds[time_dim][{ time_dim: frame_i }].values.item() # Create annotation string based on title and date specifications: title = title_list[frame_i] if title and show_date: title_date = "{}\n{}".format(date_string, title) elif title and not show_date: title_date = "{}".format(title) elif show_date and not title: title_date = "{}".format(date_string) else: title_date = "" # Update left panel with annotation and image im.set_array(imagelist[frame_i]) t.set_text(title_date) ######################## # Plot linegraph panel # ######################## # Create list of artists to return artist_list = [im, t] # Update right panel with temporal line subset, adding each new line into artist_list for i, line in enumerate(line_test.lines): # Clip line data to current time, and get x and y values y = df1[df1.index <= datetime( year=year, month=month, day=day, hour=23, minute=59)].iloc[:, i] x = df1[df1.index <= datetime( year=year, month=month, day=day, hour=23, minute=59)].index # Plot lines after stripping NaNs (this produces continuous, unbroken lines) line.set_data(x[y.notnull()], y[y.notnull()]) artist_list.extend([line]) # Return the artists set return artist_list # Nicely space subplots fig.tight_layout() ############################## # Generate and run animation # ############################## # Generate animation ani = animation.FuncAnimation( fig=fig, func=update_figure, frames=timesteps, interval=interval, blit=True, ) # Export as either MP4 or GIF if output_path[-3:] == "mp4": print(" Exporting animation to {}".format(output_path)) ani.save(output_path, dpi=width_pixels / 10.0) elif output_path[-3:] == "wmv": print(" Exporting animation to {}".format(output_path)) ani.save( output_path, dpi=width_pixels / 10.0, writer=animation.FFMpegFileWriter(fps=1000 / interval, bitrate=4000, codec="wmv2"), ) elif output_path[-3:] == "gif": print(" Exporting animation to {}".format(output_path)) ani.save(output_path, dpi=width_pixels / 10.0, writer="imagemagick") else: print(" Output file type must be either .mp4, .wmv or .gif") else: print( "Please select either one or three bands that all exist in the input dataset" ) else: print( "At least one x, y or time dimension does not exist in the input dataset. Please use the `time_dim`," "`x_dim` or `y_dim` parameters to override the default dimension names used for plotting" )
blit=False, save_count=svc, repeat=True, frames=T) plt.plot(x, a0 * np.ones_like(x), color='k') plt.title("Animation of the area of each crosssection") plt.ylabel("area (m²)") plt.xlabel("z-coordinate (m)") plt.legend(loc='lower center') # Set up formatting for the movie files ### To get an mp4-file print(plt.rcParams['animation.ffmpeg_path']) plt.rcParams['animation.ffmpeg_path'] = u'/apps/SL6.3/FFmpeg/3.1.3/bin/ffmpeg' print(plt.rcParams['animation.ffmpeg_path']) writer = animation.FFMpegFileWriter(codec='mpeg1video', metadata=dict(artist='NicolasDelaissé'), fps=24, bitrate=2000) # if bool_save: # line_ani.save(save_name, writer=writer) # # Writer = animation.writers['ffmpeg'] # writer = Writer(fps=15, metadata=dict(artist='NicolasDelaissé'), bitrate=1800) # ani.save('finer2.mp4', writer=writer) plt.show()
def animate(i): f = i / 100 resultx, resulty, crit = critical_point_interpolate(data, critical_points, f, nm * 1e-9) # crit = crit.transpose() lines.set_ydata(resulty) # markers.set_ydata(crit[1]) # markers.set_xdata(crit[0]*1e9) fig.canvas.get_tk_widget().update() # process events return lines # , markers anim = animation.FuncAnimation(fig, animate, init_func=None, frames=100, interval=2, blit=False) # anim.save('mpp.mp4', fps=30, extra_args=['-vcodec', 'libx264']) w = animation.FFMpegFileWriter(fps=10) w.fps = 10 # anim.save('ellipse.mp4', writer=w, fps=10, bitrate=100, extra_args=['-vcodec', 'libx264']) plt.show() # # print (lines) # for f in np.linspace(0.01,1,100): # resultx, resulty, crit=critical_point_interpolate(data, critical_points, f,nm) # crit = crit.transpose() # lines.set_ydata(resulty) # markers.set_ydata(crit[1]) # markers.set_xdata(crit[0]*1e9) # fig.canvas.get_tk_widget().update() # process events
def animated_doubletimeseries(ds1, ds2, output_path, width_pixels=800, interval=100, bands1=['red', 'green', 'blue'], bands2=['red', 'green', 'blue'], reflect_stand1=5000, reflect_stand2=5000, title1=False, title2=False, show_date1=True, show_date2=True, onebandplot_cbar1=True, onebandplot_cbar2=True, onebandplot_kwargs1={}, onebandplot_kwargs2={}, annotation_kwargs1={}, annotation_kwargs2={}): """ Takes two xarray time series and animates both side-by-side as either three-band (e.g. true or false colour) or single-band animations, allowing changes in the landscape to be compared across time. Animations can be exported as .mp4 (ideal for Twitter/social media), .wmv (ideal for Powerpoint) and .gif (ideal for all purposes, but can have large file sizes) format files, and customised to include titles and date annotations for each panel or use different input bands from each dataset. For example, true and false colour band combinations could be plotted at the same time, or different products (i.e. NBAR and NBART) or cloud masking algorithms could be compared. This function can be used to produce visually appealing cloud-free animations when used in combination with the `load_clearlandsat` function from `dea-notebooks/Scripts/DEADataHandling`. Last modified: May 2018 Author: Robbi Bishop-Taylor :param ds1: An xarray dataset with multiple time steps (i.e. multiple observations along the `time` dimension) to be plotted in the left panel of the animation. :param ds2: A matching xarray dataset with the same number of pixels as ds1, to be plotted in the right panel of the animation. ds1 and ds2 do not need to have exactly the same number of timesteps, but the animation will only continue up until the length of the shorted dataset (i.e. if ds1 has 10 timesteps and ds2 has 5, the animation will continue for 5 timesteps). :param output_path: A string giving the output location and filename of the resulting animation. File extensions of '.mp4', '.wmv' and '.gif' are accepted. :param width_pixels: An optional integer defining the output width in pixels for the resulting animation. The height of the animation is set automatically based on the dimensions/ratio of `ds1`. Defaults to 800 pixels wide. :param interval: An optional integer defining the milliseconds between each animation frame used to control the speed of the output animation. Higher values result in a slower animation. Defaults to 100 milliseconds between each frame. :param bands1: An optional list of either one or three bands to be plotted, all of which must exist in `ds1`. Defaults to `['red', 'green', 'blue']`. :param bands2: An optional list of either one or three bands to be plotted, all of which must exist in `ds2`. Defaults to `['red', 'green', 'blue']`. :param reflect_stand1: An optional integer controlling the brightness of the output `ds1` image. Low values (< 5000) result in brighter images. Defaults to 5000. :param reflect_stand2: An optional integer controlling the brightness of the output `ds2` image. Low values (< 5000) result in brighter images. Defaults to 5000. :param title1: An optional string or list of strings with a length equal to the number of timesteps in `ds1`. This can be used to display a static title for the left panel (using a string), or a dynamic title (using a list) that displays different text for each timestep. Defaults to False, which plots no title. :param title2: An optional string or list of strings with a length equal to the number of timesteps in `ds2`. This can be used to display a static title for the left panel (using a string), or a dynamic title (using a list) that displays different text for each timestep. Defaults to False, which plots no title. :param show_date1: An optional boolean that defines whether or not to plot date annotations for each animation frame in the left panel. Defaults to True, which plots date annotations for `ds1`. :param show_date2: An optional boolean that defines whether or not to plot date annotations for each animation frame in the right panel. Defaults to True, which plots date annotations for `ds2`. :param onebandplot_cbar1: An optional boolean indicating whether to include a colourbar for `ds1` one-band arrays. Defaults to True. :param onebandplot_cbar2: An optional boolean indicating whether to include a colourbar for `ds2` one-band arrays. Defaults to True. :param onebandplot_kwargs1: An optional dict of kwargs for controlling the appearance of `ds1` one-band image arrays to pass to matplotlib `plt.imshow` (see https://matplotlib.org/api/_as_gen/matplotlib.pyplot.imshow.html for options). This only applies if an xarray with a single band is passed to d1. For example, a green colour scheme and custom stretch can be specified using: `onebandplot_kwargs1={'cmap':'Greens`, 'vmin':0.2, 'vmax':0.9}`. By default, one-band arrays are plotted using the 'Greys' cmap with a vmin of 0.0 and a vmax of 1.0. :param onebandplot_kwargs2: An optional dict of kwargs for controlling the appearance of `ds2` one-band image arrays to pass to matplotlib `plt.imshow`; only applies if an xarray with a single band is passed to d2 (see above). :param annotation_kwargs1: An optional dict of kwargs for controlling the appearance of `ds1` text annotations to pass to matplotlib `plt.annotate` (see https://matplotlib.org/api/_as_gen/matplotlib.pyplot.annotate.html). For example, `annotation_kwargs1={'fontsize':20, 'color':'red', 'family':'serif'}. By default, text annotations are white, size 15 mono-spaced font with a 3pt black outline in the panel's top-right. :param annotation_kwargs2: An optional dict of kwargs for controlling the appearance of the `ds2` text annotations to pass to matplotlib `plt.annotate` (see above). """ # Define function to convert xarray dataset to list of three band numpy arrays def _ds_to_arrraylist(ds, bands, reflect_stand): """ This function converts xarray dataset time series into a list of numpy arrays. Output arrays will be either one or three band arrays for input into plt.imshow """ array_list = [] for i, timestep in enumerate(ds.time): # Select single timestep from the data array ds_i = ds.isel(time = i) # Create new three band array y, x = ds_i[bands[0]].shape if len(bands) == 1: # Create new three band array img_toshow = ds_i[bands[0]].values else: rawimg = np.zeros((y, x, 3), dtype=np.float32) # Add xarray bands into three dimensional numpy array for band, colour in enumerate(bands): rawimg[:, :, band] = ds_i[colour].values # Stretch contrast using defined reflectance standardisation; defaults to 5000 img_toshow = (rawimg / reflect_stand).clip(0, 1) array_list.append(img_toshow) return(array_list) def _add_colourbar(ax, im, vmin, vmax, fontsize): """ Add a nicely formatted colourbar to an animation panel """ # Add underlying bar cbbox = inset_axes(ax, '100%', '9%', loc = 8, borderpad=0) [cbbox.spines[k].set_visible(False) for k in cbbox.spines] cbbox.tick_params(axis='both', left=False, top=False, right=False, bottom=False, labelleft=False, labeltop=False, labelright=False, labelbottom=False) cbbox.set_facecolor([0, 0, 0, 0.4]) # Add colourbar axins2 = inset_axes(ax, width="90%", height="3%", loc=8) fig.colorbar(im, cax=axins2, orientation="horizontal", ticks=np.linspace(vmin, vmax, 3)) axins2.xaxis.set_ticks_position("top") axins2.tick_params(axis='x', colors='white', labelsize=fontsize, pad=1, length=0) axins2.get_xticklabels()[0].set_horizontalalignment('left') axins2.get_xticklabels()[-1].set_horizontalalignment('right') ############### # Setup steps # ############### # Get height relative to a size of 10 inches width width_ratio = float(ds1.sizes['x']) / float(ds1.sizes['y']) height = 10.0 / width_ratio # Get number of timesteps for each dataset timesteps1 = len(ds1.time) timesteps2 = len(ds2.time) # If title is supplied as a string, multiply out to a list with one string per timestep. # Otherwise, use supplied list for plot titles. if isinstance(title1, str) or isinstance(title1, bool): title_list1 = [title1] * timesteps1 else: title_list1 = title1 # If title is supplied as a string, multiply out to a list with one string per timestep if isinstance(title2, str) or isinstance(title2, bool): title_list2 = [title2] * timesteps2 else: title_list2 = title2 # Set up annotation parameters that plt.imshow plotting for single band array images. # The nested dict structure sets default values which can be overwritten/customised by the # manually specified `onebandplot_kwargs` onebandplot_kwargs1 = dict({'cmap':'Greys', 'vmin':0.0, 'vmax':1.0, 'interpolation':'bilinear'}, **onebandplot_kwargs1) onebandplot_kwargs2 = dict({'cmap':'Greys', 'vmin':0.0, 'vmax':1.0, 'interpolation':'bilinear'}, **onebandplot_kwargs2) # Set up annotation parameters that control font etc. The nested dict structure sets default # values which can be overwritten/customised by the manually specified `annotation_kwargs` annotation_kwargs1 = dict({'xy': (1, 1), 'xycoords':'axes fraction', 'xytext':(-5, -5), 'textcoords':'offset points', 'horizontalalignment':'right', 'verticalalignment':'top', 'fontsize':15, 'color':'white', 'family':'monospace', 'path_effects':[PathEffects.withStroke(linewidth=3, foreground='black')]}, **annotation_kwargs1) annotation_kwargs2 = dict({'xy': (1, 1), 'xycoords':'axes fraction', 'xytext':(-5, -5), 'textcoords':'offset points', 'horizontalalignment':'right', 'verticalalignment':'top', 'fontsize':15, 'color':'white', 'family':'monospace', 'path_effects':[PathEffects.withStroke(linewidth=3, foreground='black')]}, **annotation_kwargs2) ################### # Initialise plot # ################### # First test if there are three bands, and that all exist in both datasets: if ((len(bands1) == 3) | (len(bands1) == 1)) & all([(b1 in ds1.data_vars) for b1 in bands1]) & \ ((len(bands2) == 3) | (len(bands2) == 1)) & all([(b2 in ds2.data_vars) for b2 in bands2]): # Import xarrays as lists of three band numpy arrays imagelist1 = _ds_to_arrraylist(ds1, bands=bands1, reflect_stand=reflect_stand1) imagelist2 = _ds_to_arrraylist(ds2, bands=bands2, reflect_stand=reflect_stand2) # Test that shapes are the same: if imagelist1[0].shape[0:1] == imagelist2[0].shape[0:1]: # Set up figure fig, (ax1, ax2) = plt.subplots(ncols=2) fig.patch.set_facecolor('black') fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0) fig.set_size_inches(10.0, height * 0.5, forward=True) ax1.axis('off') ax2.axis('off') # Initialise axesimage objects to be updated during animation im1 = ax1.imshow(imagelist1[0], **onebandplot_kwargs1) im2 = ax2.imshow(imagelist2[0], **onebandplot_kwargs2) # Initialise annotation objects to be updated during animation t1 = ax1.annotate('', **annotation_kwargs1) t2 = ax2.annotate('', **annotation_kwargs2) # Optionally add colourbars for one band images if (len(bands1) == 1) & onebandplot_cbar1: _add_colourbar(ax1, im1, fontsize=11, vmin=onebandplot_kwargs1['vmin'], vmax=onebandplot_kwargs1['vmax']) if (len(bands2) == 1) & onebandplot_cbar2: _add_colourbar(ax2, im2, fontsize=11, vmin=onebandplot_kwargs2['vmin'], vmax=onebandplot_kwargs2['vmax']) # Function to update figure def update_figure(frame_i): #################### # Plot first panel # #################### # Get human-readable date info (e.g. "16 May 1990") ts = ds1.time.isel(time=frame_i).dt year = ts.year.item() month = ts.month.item() day = ts.day.item() # Create annotation string based on title and date specifications: title1 = title_list1[frame_i] if title1 and show_date1: title_date1 = '{} {} {}\n{}'.format(day, calendar.month_abbr[month], year, title1) elif title1 and not show_date1: title_date1 = '{}'.format(title1) elif show_date1 and not title1: title_date1 = '{} {} {}'.format(day, calendar.month_abbr[month], year) else: title_date1 = '' # Update figure for frame im1.set_array(imagelist1[frame_i]) t1.set_text(title_date1) ##################### # Plot second panel # ##################### # Get human-readable date info (e.g. "16 May 1990") ts = ds2.time.isel(time=frame_i).dt year = ts.year.item() month = ts.month.item() day = ts.day.item() # Create annotation string based on title and date specifications: title2 = title_list2[frame_i] if title2 and show_date2: title_date2 = '{} {} {}\n{}'.format(day, calendar.month_abbr[month], year, title2) elif title2 and not show_date2: title_date2 = '{}'.format(title2) elif show_date2 and not title2: title_date2 = '{} {} {}'.format(day, calendar.month_abbr[month], year) else: title_date2 = '' # Update figure for frame im2.set_array(imagelist2[frame_i]) t2.set_text(title_date2) # Return the artists set return [im1, im2, t1, t2] ############################## # Generate and run animation # ############################## # Generate animation frames_to_run = min(timesteps1, timesteps2) print('Generating {} frame animation (i.e. timesteps in shortest dataset)'.format(frames_to_run)) ani = animation.FuncAnimation(fig, update_figure, frames=frames_to_run, interval=interval, blit=True) # Export as either MP4 or GIF if output_path[-3:] == 'mp4': print(' Exporting animation to {}'.format(output_path)) ani.save(output_path, dpi=width_pixels / 10.0) elif output_path[-3:] == 'wmv': print(' Exporting animation to {}'.format(output_path)) ani.save(output_path, dpi=width_pixels / 10.0, writer=animation.FFMpegFileWriter(fps=1000 / interval, bitrate=4000, codec='wmv2')) elif output_path[-3:] == 'gif': print(' Exporting animation to {}'.format(output_path)) ani.save(output_path, dpi=width_pixels / 10.0, writer='imagemagick') else: print(' Output file type must be either .mp4, .wmv or .gif') else: print('Ensure that ds1 {} has the same xy dimensions as ds2 {}'.format(imagelist1[0].shape[0:1], imagelist2[0].shape[0:1])) else: print('Please select either one or three bands that all exist in the input datasets')
def init(): """FuncAnimation 所需要的动画初始设置, 返回值为零时刻的线 ln""" ax.set_xlim(0, 4 * np.pi) ax.set_ylim(-1, 1) return ln, def update(i): """ FuncAnimation 所需要的更新函数, 对于第 i 帧, 修改纵轴数据为 y 的第 i 行 返回值为更新后的第 i 帧对应的线 """ ln.set_data(x, y[i]) return ln, # 进行绘制. FuncAnimation 的函数文档: https://matplotlib.org/api/_as_gen/matplotlib.animation.FuncAnimation.html#matplotlib.animation.FuncAnimation my_ani = ani.FuncAnimation(fig=fig, func=update, frames=m, interval=1, init_func=init, blit=False) # Set up formatting for the movie files (3.7.3 报错, 3.8.5 可以) writer = ani.FFMpegFileWriter(fps=60, metadata=dict(artist='Me'), bitrate=180) # 保存图片 # my_ani.save('Harmonic.gif',writer=writer) plt.show()
interval=self.dt, blit=True, init_func=self._init, repeat=True) return ani obs_list = [] width = 6. near = width * 1.2 integration_step = 0.02 # convert from obs to point cloud # load generated point cloud writer=animation.FFMpegFileWriter(fps=int(1/integration_step)) for obs_idx in range(0,2): for p_idx in range(2): # Create custom system #obs_list = [[-10., -3.], # [0., 3.], # [10, -3.]] if os.path.exists('../acrobot_env%d_path%d.mp4' % (obs_idx, p_idx)): continue file = open('../data/acrobot_obs/obs_%d.pkl' % (obs_idx), 'rb') obs_list = pickle.load(file) file = open('../data/acrobot_obs/obc_%d.pkl' % (obs_idx), 'rb') obc_list = pickle.load(file) print('generated.') print(obs_list.shape) # load path
def animate(self, keep=[], r=0, ax=None, repeat=False, repeat_delay=None, speed=None, blit=True, moment='distribution', save=None, dpi=None, **kwargs): """ Creates an animation of the time evolution of the angle average of this kinetic quantity. :param list keep: List of time indices to keep in the plot. :param r: Radius to plot angle average for. :param ax: Axes object to use for plotting. :param bool repeat: If ``True``, repeats animation after it is finished. :param int repeat_delay: Number of milliseconds to wait before repeating animation. :param int speed: Number of milliseconds to show each frame. :param bool blit: If ``True``, use blitting to optimize drawing. :param str moment: Moment of distribution function to plot (same values as for :py:meth:`DREAM.Output.KineticQuantity.KineticQuantity.angleAveraged`). :param str save: If provided, saves the animation to the named file instead of showing it. :param int dpi: Video resolution (if saving animation to file). :param kwargs: Keyword arguments passed to ``ax.plot()``. """ show = ax is None fig = None if ax is None: fig, ax = plt.subplots() else: fig = ax.figure favg = self.angleAveraged(r=r, moment=moment) def update_ani(num, kq, ax, lines, lbl, favg, keeplines, tfac, tunit, keep): lbl.set_text(r't = {:.3f} {}'.format(kq.time[num] * tfac, tunit)) if keep is not None and num in keep: idx = keep.index(num) else: idx = None # Iterate over radii n = len(lines) for i in range(n): if favg.ndim == 3: d = favg[num, i, :] else: d = favg[num, :] line.set_data(kq.p1, d) # Keep line after time step has passed? if idx is not None: keeplines[idx * n + i].set_data(kq.p1, d) return (line, lbl) + tuple(keeplines) if speed is None: speed = 50 # Determine number of radii to plot if favg.ndim == 3: nr = favg.shape[1] elif favg.ndim == 2: nr = 1 else: raise OutputException( "Invalid number of dimensions selected to animate.") # Plot at t=0 colors = GeriMap.get(N=favg.ndim) lines = [] for i in range(nr): # Select data to plot if favg.ndim == 3: d = favg[0, i, :] else: d = favg[0, :] if 'color' not in kwargs: line, = ax.semilogy(self.p1, d, color=colors(i / (nr + 1)), **kwargs) else: line, = ax.semilogy(self.p1, d, **kwargs) lines.append(line) # Create placeholders for the 'keep' lines keeplines = [] if keep is not None: for i in range(len(keep)): for j in range(nr): if 'color' not in kwargs: l, = ax.plot([], [], linewidth=2, color=colors(j / (nr + 1)), **kwargs) else: l, = ax.plot([], [], linewidth=2, **kwargs) keeplines.append(l) # Set x/y limits fmax = np.amax(favg) xmin, xmax = self.p1[0], self.p1[-1] ymin, ymax = 1e-30 * fmax, 10 * fmax ax.set_xlim([xmin, xmax]) ax.set_ylim([ymin, ymax]) # Determine the relevant time scale tmax = self.time[-1] idx = 0 tfac = 1 tunits = ['s', 'ms', 'µs', 'ns', 'ps'] while tmax * tfac < 1 and idx < len(tunits) - 1: idx += 1 tfac = (1e3)**(idx) xp, yp = 0.60, 0.93 lymin, lymax = np.log10(ymin), np.log10(ymax) tx = xmin + xp * (xmax - xmin) ty = lymin + yp * (lymax - lymin) txt = ax.text(tx, 10**ty, r't = {:.3f} {}'.format(self.time[0] * tfac, tunits[idx]), usetex=False) ax.set_xlabel(r'$r/a$ (m)') # Create the animation ani = animation.FuncAnimation(fig, update_ani, frames=self.time.size, interval=speed, repeat_delay=repeat_delay, repeat=repeat, blit=blit, fargs=(self, ax, lines, txt, favg, keeplines, tfac, tunits[idx], keep)) # Save animation? if save: writer = animation.FFMpegFileWriter(fps=1000 / speed) writer.setup(fig, save, dpi=dpi) ani.save(save, writer=writer) print("Done saving video to '{}'.".format(save)) if show: plt.show() return ani
frames = 5000 grid = Grid(T, Ttop, Tbottom, Tleft, Tright, 0.25, 0.125) grid.iterate(frames) fig = plt.figure() ax = plt.axes(xlim=(0, 3), ylim=(0, 3)) plt.xlabel(r'x') plt.ylabel(r'y') cont = ax.contourf(X, Y, grid.getState(0), colorinterpolation, cmap=colourMap) cb = fig.colorbar(cont) anim = animation.FuncAnimation(fig, animate, fargs=(grid, ), frames=frames // 5, save_count=frames // 5) writermp4 = animation.FFMpegFileWriter(fps=50, bitrate=1800) anim.save('animação.mp4', writer=writermp4) # plt.show() #plota o perfil final fig = plt.figure() ax = plt.axes(xlim=(0, 3), ylim=(0, 3)) plt.xlabel(r'x') plt.ylabel(r'y') contourplot = plt.contourf(X, Y, grid.getState(5000), colorinterpolation, cmap=colourMap) cbar = plt.colorbar(contourplot)
def save_animation(filename, lonlat, current_velocity, states, point_types, num_iter, step): bounds_lonlat = np.hstack([lonlat.min(axis=0), lonlat.max(axis=0)]) # создаем рисунок fig, ax = plt.subplots(figsize=(12, 6)) # добавляем континенты m = Basemap( llcrnrlon=bounds_lonlat[0] - 0.03, llcrnrlat=bounds_lonlat[1] - 0.03, urcrnrlon=bounds_lonlat[2] + 0.03, urcrnrlat=bounds_lonlat[3] + 0.03, epsg="4326", resolution='h', ) m.drawcoastlines() m.fillcontinents() m.drawmapboundary() # добавляем поле скоростей q = ax.quiver( lonlat[::10, 0], lonlat[::10, 1], current_velocity[::10, 0], current_velocity[::10, 1], np.linalg.norm(current_velocity, axis=1), scale=200, scale_units='width', cmap='winter', ) # добавляем colorbar divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) plt.colorbar(q, cax=cax, label='Скорость, м/с') lines = [] colors = expand_types(point_types).color for point_ind in range(states.shape[1]): logger.debug('Рисуем частицу %s / %s', point_ind, states.shape[1]) color = list(colors.iloc[point_ind]) color[3] = 0.6 # прозрачность lines.append(ax.plot([], [], color=color, linestyle='', marker='o')[0]) # здесь пустые линии для отображения легенды # for point_type, color in point_types.color.iteritems(): # ax.plot(0, 0, color=color, linestyle='', marker='o', label='Type %d' % point_type) texts = [ ax.text(0.85, 0.3 - 0.05 * i, 'Тип %d' % (row.type), color=row.color, transform=ax.transAxes, horizontalalignment='left', verticalalignment='center') for i, row in point_types.reset_index().iterrows() ] # инициализация линий для анимации def init(): for line in lines: line.set_data([], []) return lines # обновлении линий на каждой итерации def update(frame): logger.debug('Рисуем кадр %s / %s', frame, states.shape[0]) ax.set_title('{}, час'.format(frame * step // 3600)) for point_ind, line in enumerate(lines): x, y = states[frame, point_ind, :2] if np.isinf(x) or np.isinf(y): x = np.nan y = np.nan line.set_data(x, y) return lines # cоздадим и сохраним анимацию ani = animation.FuncAnimation( fig, update, frames=num_iter - 1, init_func=init, interval=100, blit=True, ) ani.save(filename, writer=animation.FFMpegFileWriter(bitrate=-1)) logger.debug('Создан файл %s' % filename)
ax.set_frame_on(False) ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f')) # ax.view_init(azim=60) # ax.view_init(elev=20) # plt.axis('off') surf = None azim_value = int(sys.argv[1]) elev_value = int(sys.argv[2]) ax.view_init(azim=azim_value, elev=elev_value) # print ax.azim # print ax.elev # poly = PolyCollection(list(verts),facecolors=(1,1,1,1), edgecolors=(0,0,1,1)) #I'm not too bothered with # poly.set_alpha(0.7) #colours at the moment # surf = ax.plot_surface(f_f,f_f,f_f,cmap=cm.coolwarm,linewidth=0, antialiased=False) FFwriter = animation.FFMpegFileWriter(bitrate=5000000) anim = animation.FuncAnimation(fig, visualize, fargs=(complex_dft_result, result_magnititude), interval=150, blit=False, repeat_delay=0, frames=5000, repeat=False) # plt.show() result_name = img_name[0:-4] + "_" + str(azim_value) + "_" + str( elev_value) + ".mp4" anim.save(result_name)
interval=self.dt, blit=True, init_func=self._init, repeat=True) return ani obs_list = [] width = 4. near = width * 1.2 H = 0.5 L = 2.5 # convert from obs to point cloud # load generated point cloud writer = animation.FFMpegFileWriter(fps=500) for obs_idx in range(0, 2): for p_idx in range(1800, 1800 + 5): # Create custom system #obs_list = [[-10., -3.], # [0., 3.], # [10, -3.]] if os.path.exists('../cartpole_env%d_path%d_data.mp4' % (obs_idx, p_idx)): continue file = open('../data/cartpole_obs/obs_%d.pkl' % (obs_idx), 'rb') obs_list = pickle.load(file) file = open('../data/cartpole_obs/obc_%d.pkl' % (obs_idx), 'rb') obc_list = pickle.load(file) print('generated.') print(obs_list.shape)
def animate_weights(G,P,StateMonitorS,n_hidden,end=10000,start=0,save=True,show=True,step = 25): """ show(bool) : whether to show save(bool) : whether to save start(int) : start tick end(int) : end tick P,G : Neuron groups. Visualising weights from P to G StateMonitorS : brian state monitor adjusted to weights you want to visualise global_step(int) :global ticks from frame to next frame global_j(int) : global counter global_jmax : global, set to math.floor((end-start)/global_step) inside """ #step = 25 global global_step global_step = step def frames_generator(G,P,StateMonitorS,n_hidden,step=global_step,end=10000,start=0): ''' generator for speed(hope it helps) ''' #Reshape all weights as input images and put them all into one array. toanim = [] frame = start while frame < end:#in range(start,end,step): images_input = [[StateMonitorS.w[r + j * int(len(G))][frame] for j in range(len(P))] for r in range(len(G))] images_input = np.array(images_input).reshape(int(n_hidden), int(n_input_width), int(n_input_height)) together = np.hstack((images_input[0],np.ones((images_input[0].shape[0],1))*(np.nan),images_input[1],np.zeros((images_input[0].shape[0],1))*(np.nan),images_input[2])) #toanim.append(together) frame+=step #if frame> yield together #Create animation #%matplotlib osx global_j=0 global global_jmax global_jmax = math.floor((end-start)/global_step) def generate_data(): """ awful piece of code """ #global toanim global global_step global global_j global global_jmax global_j+=1 if global_j>global_jmax: global_j=global_jmax for pic in frames_generator(G,P,StateMonitorS,step=global_step,end=end,start=global_j*global_step): break return pic#.reshape((8,8)) def update(data): mat.set_data(data) return mat #def data_gen(): # while True: # yield frames_generator(G,P,StateMonitorS,step=25,end=10000,start=0) fig, ax = plt.subplots() mat = ax.imshow(generate_data(),cmap="winter",interpolation="none") plt.colorbar(mat) ani = animation.FuncAnimation(fig, update, frames_generator(G,P,StateMonitorS,step=global_step,end=end,start=start), interval=10, save_count=399) #Show animation if show: plt.show() if save: #Saving animation as mp4 file ani.save('MaWheightsAnimation.mp4',writer=animation.FFMpegFileWriter())