class player_base: r""" An instance of this class controls the exploration of a fractal. :param display: a function which, given a zoom level and possibly its new specification, displays it on the board """ #================================================================================================== def __init__(self, display: Callable[[int, Any], None], **ka): def frames(): self.select(None) self.setrunning(False) yield None while True: yield self.level self.level = -1 self.anim = FuncAnimation( self.board, (lambda i: None if i is None else self.show_precision(display(i))), frames, init_func=(lambda: None), repeat=False, **ka) def setrunning(self, b: bool = None): r"""Sets the running state of the animation to *b* (if :const:`None`, the inverse of current running state).""" if b is None: b = not self.running self.running = b if b: self.anim.resume() else: self.anim.pause() self.show_running(b) def show_running(self, b: bool): r"""Shows the current running state as *b*. This implementation raises an error.""" raise NotImplementedError() def show_precision(self, p: int): r"""Shows the current precision as *p*. This implementation raises an error.""" raise NotImplementedError() def select(self, bounds: Union[Tuple[Tuple[float, float], Tuple[float, float]], None]): r"""Pushes a new level in the animation at the current level plus one. This implementation raises an error.""" raise NotImplementedError()
class AnimDialog(qt.QDialog): def __init__(self, nbrs, pop, Ti, Tr): super().__init__() self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.fig = Figure() self.canvas = FigureCanvasQTAgg(self.fig) self.toolbar = NavigationToolbar2QT(self.canvas, self) self.anim_obj = None self.playPause = PlayPause() self.axes = [ self.fig.add_subplot(121), self.fig.add_subplot(222), self.fig.add_subplot(224) ] self.im = _pop_image(self.axes[0], pop, Ti, Tr) self.ln = _timeSeriesLines(self.axes[1], np.zeros(shape=(0, 6))) self.ln.append(*self.axes[2].plot([], [], lw=2)) self._title(Ti, Tr, nbrs) self._set_all_layouts() def _title(self, Ti, Tr, nbrs): tau_i = r'$\tau_{i}$=%i' % Ti tau_r = r'$\tau_{r}$=%i' % Tr nbrs = f'nbrs={nbrs}' self.axes[1].set_title(f'Time Series\t{tau_i}\t{tau_r}\t{nbrs}') ham_dist_phase = r'|$\frac{1}{N}\Sigma e^{i\phi}$|' self.axes[2].set_title(f'Order Parameter = {ham_dist_phase}') def _update(self, i, dataUpdates): pop, data = dataUpdates() self.im.set_data(pop) self.ln[0].set_data(data[:, 0], data[:, 1]) self.ln[1].set_data(data[:, 0], data[:, 2]) self.ln[2].set_data(data[:, 0], data[:, 3]) self.ln[3].set_data(data[:, 0], data[:, 4]) t0, (t, fs, fi, fr, _) = data[0, 0], data[-1] self.axes[0].set_title(_sirTitle(t, fs, fi, fr)) self.axes[1].set_xlim(t0, t + 1) self.axes[2].set_xlim(t0, t + 1) def animate(self, ti, tf, delay, dataUpdates): from matplotlib.animation import FuncAnimation self.anim_obj = FuncAnimation(self.fig, self._update, (tf - ti - 1), fargs=(dataUpdates, ), interval=delay * 1000, repeat=False) self.playPause.animControler = self.anim_obj self.canvas.draw() def closeEvent(self, *args): self.anim_obj.pause() def reject(self, *args): self.close() def _set_all_layouts(self, width=5, height=4): hl = qt.QHBoxLayout() hl.addStretch() hl.addWidget(self.playPause) hl.addWidget(self.toolbar) layout = qt.QVBoxLayout() layout.addWidget(self.canvas) layout.addLayout(hl) self.setLayout(layout) self.setWindowTitle('Time evolution animation') self.showMaximized() # self.resize(1200, 650) self.axes[1].set_ylim(0.0, 1.0) self.axes[1].legend(loc='upper right') self.axes[2].set_ylim(-1, 3) self.fig.tight_layout() self.show()
]) # + fig, ax = plt.subplots() lines, = ax.plot([], [], marker='.', c='black', ls='') anim = Animation(24, fig, lines=lines) x1 = np.random.uniform(0, 1, 100) x2 = np.random.uniform(0, 1, 100) y1 = np.random.uniform(0, 1, 100) y2 = np.random.uniform(0, 1, 100) anim.show_points(x1, y1) anim.pause() anim.transform(x1, x1, y1, y2) anim.transform(x1, x2, y2, y2) anim.animate() # + fig, ax = plt.subplots() lines, = ax.plot([], [], marker='.', c='black', ls='') anim = Animation(24, fig, lines=lines) y = np.random.uniform(0, .6, 100) y.sort() y2 = y + np.linspace(.4, 0, 100)
class BoundedEquationService( DifferentialEquationService[BoundedEquationMetadata], ABC): __animation: Optional[FuncAnimation] = None __is_animation_playing: bool = False def __init__(self, main_figure: Figure): super().__init__(main_figure) def render_current_solution(self): self.clear_figure() self.clear_animation() K, N = self.solution.shape time_domain = np.linspace(0, self.metadata.time, K) space_domain = np.linspace(0, self.metadata.length, N) x, t = np.meshgrid(space_domain, time_domain) ax = self.main_figure.add_subplot(projection='3d') ax.set_xlabel('x [length]') ax.set_ylabel('t [time]') ax.set_zlabel('u(x, t)') surf = ax.plot_surface(x, t, self.solution, cmap=cm.coolwarm, linewidth=0, antialiased=False) self.main_figure.colorbar(surf, shrink=0.5, aspect=5) def generate_animation(self): self.clear_figure() K, N = self.solution.shape ax = self.main_figure.add_subplot() Axes.set_xlim(ax, left=0, right=self.metadata.length) Axes.set_ylim(ax, bottom=np.min(self.solution), top=np.max(self.solution)) ax.set_xlabel("x [length]") ax.set_ylabel("u(x, t)") ax.set_title("Solution: u(x, t)") space_domain = np.linspace(0, self.metadata.length, self.metadata.samples) line, = ax.plot(space_domain, self.solution[0], "-o", markersize=4) time_text = ax.text(0.82, 0.92, '', transform=ax.transAxes) dt = self.metadata.time / K def update_plot(k: int): line.set_ydata(self.solution[k]) time_text.set_text("t = %.3f" % (k * dt)) return line, time_text self.__animation = FuncAnimation(self.main_figure, update_plot, frames=K, blit=True, interval=20) def toggle_animation(self): if not self.__animation: self.generate_animation() self.__is_animation_playing = True elif self.is_animation_playing(): self.__animation.pause() self.__is_animation_playing = False else: self.__animation.resume() self.__is_animation_playing = True def is_animation_playing(self): return self.__is_animation_playing def export_solution(self, table_path: str): K, N = self.solution.shape time_domain = np.linspace(0, self.metadata.time, K) space_domain = np.linspace(0, self.metadata.length, N) workbook = Workbook() worksheet = workbook.active worksheet.cell(1, 2, "x →") for i in range(N): worksheet.cell(1, 3 + i, space_domain[i]) worksheet.write(2, 1, "t ↓") for k in range(K): worksheet.write(3 + k, 1, time_domain[k]) for k in range(K): for i in range(N): worksheet.write(k + 3, i + 3, self.solution[k, i]) workbook.save(table_path) def clear_animation(self): if self.__animation: self.__animation.pause() self.__animation = None self.__is_animation_playing = False self.main_figure.clf()