def anim(sername, simname): sim = Simulation(sername, simname) # https://github.com/matplotlib/matplotlib/issues/16965 anim_fn = os.path.join(CACHEDIR, "graphics", sername, simname, f"{simname}.gif") os.makedirs(os.path.dirname(anim_fn), exist_ok=True) base_fn = sim.data_fn() if flask.request.values.get("maxind"): max_data_index = int(flask.request.values.get("maxind")) else: max_data_index = sim.status()['dataFileCounter'] datafiles = [f"{base_fn}.{ind}" for ind in range(max_data_index)] if (flask.request.values.get("nocache") or need_to_regenerate(anim_fn, datafiles)): ani = create_animation(sername, simname, maxframes=max_data_index, samplesize=3000) ani.save(anim_fn, writer="imagemagick") # ani.save(anim_fn, writer="ffmpeg") if flask.request.values.get("format") == "webm": clip = mp.VideoFileClip(anim_fn) webm_fn = f"{anim_fn}.webm" clip.write_videofile(webm_fn) with open(webm_fn, "rb") as webm_f: return Response(webm_f.read(), mimetype="video/webm") else: with open(anim_fn, "rb") as anim_f: return Response(anim_f.read(), mimetype="image/gif")
class AnimatedScatter(object): """An animated scatter plot using matplotlib.animations.FuncAnimation.""" # https://stackoverflow.com/questions/9401658/how-to-animate-a-scatter-plot def __init__(self, sername, simname, maxframes, samplesize): self.sername = sername self.simname = simname self.sim = Simulation(sername, simname) self.samplesize = samplesize # self.stream = self.data_stream() # Setup the figure and axes... self.fig = plt.Figure(figsize=(12, 6)) self.ax = self.fig.add_subplot(1, 1, 1) # Then setup FuncAnimation. self.ani = FuncAnimation(self.fig, self.update, interval=5, frames=maxframes, init_func=self.setup_plot, blit=True) def setup_plot(self): """Initial drawing of the scatter plot.""" x, y, s, c = [], [], [], [] self.scat = self.ax.scatter(x, y, c=c, s=s, vmin=0, vmax=1, cmap="jet", edgecolor="k") # self.ax.axis([-10, 10, -10, 10]) # For FuncAnimation's sake, we need to return the artist we'll be using # Note that it expects a sequence of artists, thus the trailing comma. return self.scat, def update(self, ind): """Update the scatter plot.""" # data = next(self.stream) data_fn = self.sim.data_fn(ind) print(ind) print(data_fn) data_df, dimensions, headline = read_data_file(data_fn) num, time, xmin, ymin, zmin, xmax, ymax, zmax = headline self.ax.set_xlim((xmin, xmax)) self.ax.set_ylim((ymin, ymax)) self.scat = self.ax.scatter(data_df.x, data_df.y, s=np.sqrt(data_df.r), c=data_df.sp, cmap=plt.get_cmap("viridis", 3), vmin=0, vmax=2) # We need to return the updated artist for FuncAnimation to draw.. # Note that it expects a sequence of artists, thus the trailing comma. return self.scat,
def showdataplot_page(sername, simname, ind): """A page that contains a .data file's plot.""" sim = Simulation(sername, simname) simstatus = sim.status() max_data_index = simstatus['dataFileCounter'] - 1 data_df, dimensions, headline = read_data_file(sim.data_fn(ind)) num, time, xmin, ymin, zmin, xmax, ymax, zmax = headline if dimensions == 2: return render_template("results/data2d_plot.html", sername=sername, simname=simname, ind=ind, time=time, dt=simstatus['timeStep'] * simstatus['dataFileSaveCount'], lines=data_df, mdi=max_data_index) elif dimensions == 3: return render_template("results/data3d_plot.html", sername=sername, simname=simname, ind=ind, time=time, dt=simstatus['timeStep'] * simstatus['dataFileSaveCount'], lines=data_df, mdi=max_data_index) else: raise ValueError("Number of dimensions should be 2 or 3.")
def animate(ind): sim = Simulation(sername, simname) data_fn = sim.data_fn(ind) data_df, dimensions, headline = read_data_file(data_fn) num, time, xmin, ymin, zmin, xmax, ymax, zmax = headline if samplesize: try: data_df = data_df.sample(n=samplesize) except ValueError: pass ax.set_xlim([xmin, xmax]) ax.set_ylim([ymin, ymax]) pts = [(p.x, p.y) for p in data_df.itertuples()] path_collection.set_offsets(pts) path_collection.set_sizes(np.sqrt(data_df.r)) path_collection.set_array(data_df.sp) return path_collection,
def data_plot_figview(sername, simname, ind): """A plot of a .data file, in PNG format by default.""" sim = Simulation(sername, simname) format = flask.request.values.get("format", "png") if format not in ["png", "svg", "pdf"]: raise NotImplementedError data_fn = sim.data_fn(ind) dataplot_fn = os.path.join(CACHEDIR, "graphics", sername, simname, f"{simname}.data.{ind}.{format}") logging.info("Generating a new image") os.makedirs(os.path.dirname(dataplot_fn), exist_ok=True) fig = create_data_figure(data_fn, **floatify(flask.request.values)) fig.savefig(dataplot_fn, format=format) with open(dataplot_fn, "rb", buffering=0) as dataplot_f: return Response(dataplot_f.read(), mimetype=MIMETYPE[format])
def depth_plot_figview(sername, simname, ind): sim = Simulation(sername, simname) data_fn = sim.data_fn(ind) format = flask.request.values.get("format", default="png") if format not in ["png", "svg", "pdf"]: raise NotImplementedError plot_fn = os.path.join(CACHEDIR, "graphics", sername, simname, ".".join([simname, "depth", ind, format])) logging.info(plot_fn) logging.info("Generating a new image") os.makedirs(os.path.dirname(plot_fn), exist_ok=True) fig = plot_depth(data_fn, **floatify(flask.request.values)) with NamedTemporaryFile(suffix="." + format) as ntf: fig.savefig(ntf, format=format) ntf.seek(0) return Response(ntf.read(), mimetype=MIMETYPE[format])
def cg_plot_figview(sername, simname, ind, field): if field not in {"depth", "rho", "px", "py", "u", "v"}: raise NotImplementedError format = flask.request.values.get("format", "png") if format not in ["png", "svg", "pdf"]: raise NotImplementedError sim = Simulation(sername, simname) data_fn = sim.data_fn(ind) logging.info("Generating new CG plots") cgfigs = plot_all_cg_fields(data_fn, kernel_width=0.4, **floatify(flask.request.values)) with TemporaryDirectory() as td: fn = os.path.join(td, ".".join([simname, field, ind, format])) cgfigs[field].savefig(fn, format=format) with open(fn, "rb", buffering=0) as plot_f: return Response(plot_f.read(), mimetype=MIMETYPE[format])
def showdatafile(sername, simname, ind): sim = Simulation(sername, simname) simstatus = sim.status() max_data_index = simstatus['dataFileCounter'] - 1 max_fstat_index = simstatus['fStatFileCounter'] - 1 ind = int(ind) if ind > max_data_index: return f"The index {ind} is greater than the maximum index {max_data_index} so far", 400 try: data_df, dimensions, headline = read_data_file(sim.data_fn(ind)) except FileNotFoundError: return f"{sim.data_fn(ind)} not found" num, time, xmin, ymin, zmin, xmax, ymax, zmax = headline if dimensions == 2: return render_template("results/data2d.html", sername=sername, simname=simname, ind=ind, time=time, dt=simstatus['timeStep'] * simstatus['dataFileSaveCount'], lines=data_df, mdi=max_data_index) if dimensions == 3: return render_template("results/data3d.html", sername=sername, simname=simname, ind=ind, time=time, dt=simstatus['timeStep'] * simstatus['dataFileSaveCount'], lines=data_df, mdi=max_data_index)
def serve_data_raw(sername, simname, ind): """Serve a raw .data. file.""" sim = Simulation(sername, simname) dat_fn = sim.data_fn(ind) dat_f = open(dat_fn, "r") return Response(dat_f.read(), mimetype="text/plain")